Skip to content

Boot Sequence

opencode-agent[bot] edited this page May 11, 2026 · 2 revisions

Boot Sequence

JNode boots from GRUB via Multiboot, transitions through x86 assembly setup to Java's Main.vmMain(), which initializes the VM and starts plugins.

Overview

The boot sequence has three major phases:

  1. Native bootstrap — GRUB → kernel.asm → CPU/memory setup
  2. VM initializationVmSystem.initialize() brings up the Java runtime
  3. Plugin startupMain.vmMain() loads and starts system plugins

Phase 1: Native Bootstrap

GRUB / Multiboot

The boot image is a Multiboot-compliant ELF binary built by BootImageBuilder. GRUB loads it and jumps to sys_start in kernel.asm with:

  • EAX = 0x2BADB002 (Multiboot magic)
  • EBX = pointer to Multiboot info structure

kernel.asm — Entry Point

File core/src/native/x86/kernel.asm
sys_start → real_start:
  1. Set up kernel stack (Lkernel_esp)
  2. Clear screen
  3. Verify Multiboot magic (0x2BADB002)
  4. Copy Multiboot info block
  5. Detect CPU features (CPUID)
  6. Set up GDT, IDT
  7. Enable paging (mm32.asm / mm64.asm)
  8. Jump to VM entry point

Supporting Assembly Files

File Role
kernel.asm Main entry, Multiboot header, CPU init
mm32.asm 32-bit memory management, page tables
mm64.asm 64-bit memory management, page tables
cpu.asm / cpu32.asm CPU detection, feature flags
ints.asm / ints32.asm / ints64.asm Interrupt descriptor table, IRQ handlers
console.asm Early VGA text console output
ap-boot.asm Application processor bootstrap (SMP)

Phase 2: VM Initialization

VmSystem.initialize()

File core/src/core/org/jnode/vm/VmSystem.java

Called from Main.vmMain(). Sets up:

  1. Boot loggingBootLogInstance for early console output
  2. System classloaderVmSystemClassLoader with pre-loaded boot classes
  3. System propertiesjava.home, os.name, etc.
  4. Memory manager — Heap initialization, GC setup
  5. SchedulerVmScheduler starts the idle thread and timer
  6. I/O system — Console streams (System.out, System.err)
  7. Log4j — Sets up logging via ConsoleAppender

Phase 3: Plugin Startup

Main.vmMain()

File core/src/core/org/jnode/boot/Main.java

After VmSystem.initialize():

  1. Load initjarInitJarProcessor extracts plugin JARs and descriptors from the embedded init-jar
  2. Create PluginManagerDefaultPluginManager manages the plugin lifecycle
  3. Start system pluginspiMgr.startSystemPlugins(descriptors) activates all plugins in dependency order
  4. Launch main class — Reads Main-Class from the plugin list manifest (typically org.jnode.shell.CommandShell) and invokes its main() method

Plugin Loading Order

Plugins are started in dependency order. The default plugin list (all/conf/default-plugin-list.xml) specifies:

  1. Core classpath extensions (org.classpath.ext.*)
  2. Driver framework (org.jnode.driver)
  3. Block devices and partitions
  4. Filesystem service
  5. Console and input drivers
  6. Shell and commands
  7. Network stack (if included)
  8. GUI (if included)

Key Annotations in Boot Path

Annotation Effect
@Uninterruptible Method must not be interrupted (no GC safepoints)
@LoadStatics Static fields are initialized at boot time, not build time
@SharedStatics Static fields are shared across all isolates
@KernelSpace Method runs in kernel context

Main.vmMain() is annotated with both @LoadStatics and @Uninterruptible because it runs before the scheduler and GC are fully operational.

Gotchas & Non-Obvious Behavior

  • Build time vs. boot timeBootImageBuilder pre-compiles classes and serializes static fields into the image. @LoadStatics marks fields that should be re-initialized at actual boot rather than using build-time values.
  • pluginRegistryMain.pluginRegistry is set by BootImageBuilder.initMain() during image creation, not at runtime.
  • No exceptions before VmSystem.initialize() — The exception handling machinery isn't ready until the VM is initialized. Early boot code uses Unsafe.debug() for output.
  • The initjar — This is a nested archive inside the boot image containing all plugin JARs. It's created by the build process and accessed via VmSystem.getInitJar().

Related Pages

Clone this wiki locally