Hi,
I just wish I had enough time to dive into JNode topics, like when I was a kid...
With that said, I have been analysing JNode code for a while and came up with a notion of what I see that JNode needs (others might not share my opinion, but still it won't hurt to make it public, will it?)
I see JNode as a layered architecture containing the following layers (from bottom to top):
- the boot loader: that is GRUB with BIOS and MBR
- the nano kernel: that is the little assembly code in core/src/native which boots, initialises base hardware (CPU, threading, memory management, mostly) and provides the driver to load and run the Java-compiled code
- the VM: that is mostly Java code, with some magical additions, and a good compiler, able to translate byte codes to x86/x64 machine code
- the module infrastructure: that is mostly Java code, that acts like an OSGi container, only proprietary, loading JNode modules and establishing a lifecycle for them
- the user land: that is mostly the applications, commands, drivers, etc.
In order to scale, I would see these layers as being as independent as possible from each other, and maybe handled and evolved by independent teams. That only works if there are well-defined, well-known and published interface standards between the layers, of course.
I could go over enhancements for a long while, while others might have greater insight of some of those layers that I lack and would do a better job at providing suggestions. No matter, what I want to discuss are two specific changes I would see as greatly simplifying further developments.
a. 2-3 separation:
Currently the ant-based build process is centered around the bootimagebuilder task and the companion constant generator task that runs just before, which assembles the main binary which becomes the kernel. Inputs to that are the various jar files generated by the different ant scripts, corresponding to each pure Java module (core, drivers, fs, net, gui, etc.) as well as external dependencies, sometimes packaged as modules. But I am starting to digress.
The point to bootimagebuilder is it inspects the Java compiled code and provides a number of constants, mostly offsets into some class' binary layout, that tells where a given field can be accessed within a given object. That is mostly understandable, because there are abstractions to very low-level concepts, like processor and thread, that are actually written in Java. However, they are needed in the low-level nano kernel (layer 2) that is written in assembly language and needs those objects laid out in memory and functional way before any VM is running. So the constant generator task creates that java.inc assembly file, which the nano kernel will include and use as an input to its own compilation. And that also means, once the nano kernel is built those little magical classes and fields are carved in nano kernel stone, that is, they cannot be changed. If you for any reason get those classes changed, their offsets will be wrong in the binary nano kernel image. That creates a dependency between the nano kernel and a little part of the Java code, that poses limitations to its replacement without a rebuild. Effectively, those classes (not many, but still a handful) are part of the nano kernel, though not coded in assembly.
So, what I want to suggest is, why not do away with that? Fact is, it is not so simple. To be able to extract those constants from class files at runtime would take parts of the VM to be implemented in assembly and built into the nano kernel (some kind of reflection library in assembly, maybe). That is not the purpose of my modularisation case. But I looked into the multiboot specification and noticed there is a reasonably feasible way.
Currently the grub configuration for JNode specifies the kernel, which is this bootimagebuilder output, and also a module, which is the init jar image you choose to boot it with. So why not have the constant generator generate, instead of an assembly file, a table-like structure in a binary file (TLV encoding, maybe? -- better suggestions welcome) and load that as the first multiboot module (the init jar becomes the second)? The nano kernel would have to be modified to eliminate direct references to those constants in the assembly code and instead define specific variables to hold those, which would then be loaded from the constants module and patched in very early at runtime.
So, what does one gain from this added complexity? IMHO, the nano kernel becomes an independent portion of code, that can be separately developed and optimised to take advantage of hardware trends, added support to EFI and whatever, and even be ported to different platforms (ARM, etc.). Hand the nano kernel assembly code to the experts in assembly and free it to evolve looking towards the hardware evolution. Just make it honor the interface to the upper layer which was already there. Java folks want to add a variable to the VMThread class? ok, just regenerate the constant table and it will be reloaded with no changes to the same nano kernel already deployed.
Likewise, layer 3 can evolve independently, providing newer OpenJDK 7, 8 (maybe 9) compatibility without the need to look down to the assembly code every time a new change is built. Also, the emulator becoming a full-fledged layer 1/2/3 that runs on top of stock Java VMs and provides the same base to layers above would be a greatest achievement.
Layer 4 could evolve by providing a standard OSGi container (if at all possible the same binary that could run in any Java platform).
Layer 5 is up to the OS designers best taste and trends. (Though I would like to see some production-grade improvements in the longer term -- IPv6?)
Around and in between all these layers, lies the build system. I could call it layer 0, but it is not actually a layer. It is the glue. I would love to see that become Maven-based, with modules being downloaded off Central, as you boot a minimal init jar with networking capabilities.
These are my views on modularising JNode. If they are not all feasible or even desirable, at least I would rather have them documented and submitted to scrutiny. I suppose specification should be the first contribution towards evolving JNode.
Cheers,
Douglas