Skip to content

Build System

opencode-agent[bot] edited this page Aug 30, 2026 · 4 revisions

Build System

JNode uses Apache Ant for builds, with a custom BootImageBuilder that compiles Java classes and assembles them into a bootable ISO image.

Overview

The build system compiles ~3,300 Java files, assembles x86 native code with JNasm (a custom Java assembler), links everything into a boot image, and wraps it in a bootable ISO. The entire process runs on a host JVM (Java 1.6–1.8).

Quick Reference

Action Command
Build x86 lite ISO sh build.sh cd-x86-lite
Build x86_64 lite ISO sh build.sh cd-x86_64-lite
Build combined 32+64-bit ISO sh build.sh cd-x86-combined-lite
Build bootable USB disk sh build.sh disk
Assemble only sh build.sh assemble
Run all tests sh build.sh tests
Per-subproject tests cd <subproject> && ant test

Output: all/build/cdroms/jnode-x86-lite.iso (or x86_64 / x86-combined-lite)

Build Pipeline

  Source Code          Compile            Assemble           Package
┌─────────┐     ┌──────────────┐    ┌───────────────┐   ┌──────────┐
│ Java    │────▶│ javac (1.6)  │───▶│BootImageBuilder│──▶│ ISO      │
│ files   │     │ per subprj   │    │ + JNasm        │   │ (GRUB +  │
│         │     └──────────────┘    │ + initjar      │   │  image)  │
├─────────┤                         └───────────────┘   └──────────┘
│ .asm    │─────────────────────────────────▲
│ files   │     JNasm assembler             │
├─────────┤                                 │
│ plugin  │     Descriptor processing       │
│ XMLs    │─────────────────────────────────┘
└─────────┘

Key Build Components

build.sh / all/build.xml

  • build.sh is a thin wrapper that invokes ant with the specified target in all/build.xml
  • all/build.xml is the master build file that orchestrates all sub-project builds
  • Each sub-project has its own build.xml and build-tests.xml

BootImageBuilder

File builder/src/builder/org/jnode/build/x86/BootImageBuilder.java

The BootImageBuilder is the heart of the build:

  1. Loads all compiled classes
  2. Pre-compiles selected methods using the L1 JIT compiler (running on the host JVM)
  3. Lays out objects in memory (class metadata, vtables, static fields)
  4. Assembles native code via JNasm
  5. Writes the boot image binary
  6. Packages it with GRUB into a bootable ISO

JNasm

Directory builder/src/builder/org/jnode/jnasm/

A custom x86 assembler written in Java. Assembles the .asm files in core/src/native/x86/ into native code that gets linked into the boot image.

Classlib

  • Downloaded during build to all/lib/classlib.jar
  • Provides the GNU Classpath / OpenJDK standard library classes
  • Source also available as classlib-src.jar

Plugin Descriptors

Each plugin has an XML descriptor in <subproject>/descriptors/:

<plugin id="org.jnode.driver.video.vga"
        name="JNode Video Standard VGA driver"
        version="@VERSION@"
        provider-name="JNode.org">
  <requires>
    <import plugin="org.jnode.driver.bus.pci"/>
    <import plugin="org.jnode.driver.video.vgahw"/>
  </requires>
  <runtime>
    <library name="jnode-gui.jar">
      <export name="org.jnode.driver.video.vga.*"/>
    </library>
  </runtime>
  <extension point="org.jnode.driver.bus.pci.device-factories">
    <device-factory class="..." />
  </extension>
</plugin>

The build system processes these descriptors to:

  • Resolve plugin dependencies
  • Build the init-jar with all required plugins
  • Set up the classloader hierarchy

Plugin Lists

File Purpose
all/conf/default-plugin-list.xml Default plugins for a standard build
all/conf/full-plugin-list.xml All available plugins

The plugin list also specifies the main class to launch after boot:

<manifest>
    <attribute key="Main-Class" value="org.jnode.shell.CommandShell"/>
    <attribute key="Main-Class-Arg" value="boot"/>
</manifest>

Configuration

jnode.properties

Build-time configuration file. Key settings include:

  • Java compiler source/target level
  • Platform selection (x86 / x86_64)
  • Memory layout parameters
  • Plugin list selection

Note: jnode.properties is gitignored. Copy from jnode.properties.dist and customize.

Test Infrastructure

  • Framework: JUnit 4.5, JMock, Mockito
  • Test source: <subproject>/src/test/
  • Run all: sh build.sh tests
  • Run per-subproject: cd <subproject> && ant test
  • 390 test files across all sub-projects

Gotchas & Non-Obvious Behavior

  • Java 1.6 target — All source must compile with -source 1.6 -target 1.6. No lambdas, no try-with-resources, no diamond operator.
  • US-ASCII encoding — Source files must be US-ASCII. No Unicode in source code.
  • Host JVM vs. target — The build runs on a standard JVM, but the output runs on JNode's own VM. Some code has different behavior in these two contexts.
  • @LoadStatics — Build-time static initializers run on the host JVM. Fields marked @LoadStatics are re-initialized on the target at boot.
  • classlib.jar — Downloaded automatically during the first build. If the download fails, the build fails. Check network connectivity.
  • Build time — A full build takes several minutes. Use assemble for code-only changes without ISO generation.

Multi-Architecture Builds

The build system supports building for multiple architectures from a single source tree:

  • cd-x86-lite: 32-bit kernel only (jnode32.gz)
  • cd-x86_64-lite: 64-bit kernel only (jnode64.gz)
  • cd-x86-combined-lite: Both 32-bit and 64-bit kernels with a GRUB menu offering both options
  • disk: Bootable USB disk image (jnode.dat) with combined 32+64-bit kernels

The combined ISO and USB disk targets use separate GRUB menu files (menu-cdrom-combined.lst, menu-disk-combined.lst) that present paired 32-bit and 64-bit entries for each boot mode.

BootImageBuilder debug text dump is gated to 32-bit only — the 64-bit path returns the raw assembler directly.

USB Disk Target

The disk target creates a bootable USB disk image (jnode.dat) using BootDiskBuilder with bits="combined":

  • Combines both jnode32.gz and jnode64.gz kernels
  • Uses GRUB menu with 10 entries (32/64-bit variants for default, all-plugins, shell, tests, install)
  • FAT16 geometry: 128 cylinders × 63 heads × 63 sectors (~248MB)
  • All plugin jars (*.jgz) are included

Related Pages

Clone this wiki locally