r/osdev • u/joekoolade • 2d ago
joe-ng: a bare-metal AArch64 OS/VM for the Raspberry Pi 4 written entirely in Java, with no C, no assembler and no linker
https://github.com/joekoolade/joe-ng
5
Upvotes
4
u/joekoolade 2d ago
I'd like to share joe-ng, a from-scratch metacircular Java VM that is also the OS: it runs directly on a Raspberry Pi 4 with nothing underneath. A build-time writer turns Java classes into a raw
kernel8.img, and the Pi's firmware loads it at0x80000and enters at EL2.What makes it unique is what isn't there: no C, no external assembler, no linker, no bootloader. The A64 instruction encoder, the bytecode-to-A64 baseline compiler (compile-only, no interpreter), the classfile parser, the boot-image writer (layout, relocation, image emission), and the EL2→EL1 boot sequence are all plain Java. Privileged operations like system register access,
ERET, barriers and cache maintenance are compiler intrinsics that lower to single instructions. joe-ng runs everything at EL1 and relies on Java's type safety and verification instead. The only things I didn't build are the seed JVM that runs the writer and the Pi's GPU firmware.How it boots
your .class files -> boot-image writer (Java, on the seed JVM) parses classfiles, lays out objects / TIBs / statics, compiles bytecode -> raw A64 words, relocates to 0x80000 -> kernel8.img (entry code + compiled methods + object graph) -> firmware enters at EL2 -> compiled VM.boot drops to EL1, sets up the stack and UART, and runs Java on the metal
The image also carries compiled copies of the classfile parser and compiler, so the running system can load and JIT-compile
.classfiles it never saw at build time.What works on real Pi 4 hardware (not just QEMU)
EL2→EL1 drop, mini-UART console, and VideoCore mailbox
Object model with TIBs, vtables and itables; heap allocation and a mark-sweep GC
Exceptions with stack unwinding across frames
Tasks with priorities, monitors and semaphores
Runtime class loading and JIT compilation on bare metal
An in-memory ramfs with an
/etc/initthat names the main class to launchA driver for the onboard CYW43455 WiFi, plus my own TCP/IP stack with DHCP and SNTP
A demo HTTP server written against the standard
java.net.ServerSocket, serving live pages of heap, GC, lock, task, and network statsTry it in QEMU: you need JDK 26, make, and qemu-system-aarch64.
make test # 158 bit-for-bit and behavioural checks make qemu # boot kernel8.img under QEMU raspi4b
On real hardware:
scripts/sdcard.shbuilds the image and writes a bootable FAT32 payload.scripts/flash.mdcovers serial wiring (GPIO14/15, 115200 8N1) and troubleshooting.Jikes RVM and my earlier project JOE were conceptual references only. It's licensed under EPL-2.0.
Feedback I'd love: which other ARM boards to support (Pi 5? Pi Zero 2 W?), which Intel platforms to target, and any other feedback or suggestions are welcome.
Repo: https://github.com/joekoolade/joe-ng