ReviewOS

home-lang/home-os

MVK pipeline: compile → link → multiboot2 ELF → QEMU proof-of-life

#26
Closed chris opened this 8 days ago ·
8 days ago

The core Phase 0 deliverable: first end-to-end compile of Home-generated kernel code.

Scope:

  • Build the Appendix-A Minimum Viable Kernel file-set (41 source files + linker script)
  • Entry point kernel/src/main.home (not kernel_main.home)
  • x86-64 freestanding codegen → link via kernel/linker.ld → multiboot2-loadable ELF
  • Proof-of-life string HomeOS <version>: kernel_main reached on serial in QEMU

Depends on compiler milestones A2/A3/A4 landing in home-lang/home. Part of #21.

8 days ago

Done — a Home-compiled kernel boots.

kernel/src/mvk_poc.home compiles through the Home compiler, links with kernel/src/boot.s via kernel/linker.ld, and boots in QEMU:

$ ./scripts/build.sh mvk
[OK] MVK built: kernel/build/home-kernel.elf
$ ./scripts/boot-test.sh
--- serial output ---
HomeOS v0.1: kernel_main reached
---------------------
PASS: proof-of-life string found on serial.

Two things had to be solved that the issue did not anticipate:

1. QEMU cannot load a multiboot2 ELF64. Its -kernel loader implements only Multiboot1, and that path rejects 64-bit images outright (Cannot load x86-64 image, give a 32bit one). Rather than require GRUB and an ISO in a gate that runs on every commit, boot.s now carries both headers: Multiboot2 for GRUB (the real install path, unchanged) and Multiboot1 with the a.out kludge (flag 16) for QEMU. The kludge makes the loader skip ELF parsing and copy a flat image to load_addr, so the build also emits home-kernel.bin via objcopy and QEMU is handed that. linker.ld exports __load_end and __bss_end for the kludge header, and both headers moved into a .multiboot section that the linker KEEPs at the image start so neither can drift past its offset limit.

2. The Home compiler's kernel codegen emitted every assembly line without a terminator — HomeKernelCodegen.print() appends verbatim and most call sites omitted the \n, so labels, directives and instructions all landed on one line. Fixed upstream in home-lang/home@71d5731.

mvk_poc.home is deliberately written inside the current kernel-codegen subset (integer literals, local calls, simple-form inline asm), which is why the message is spelled out through putc() calls. Widening that subset — string literals, then the MVK file-set in Appendix A — is the Phase 1 codegen work.

Commits: 705a2e5 (home-os), 71d5731 (home-lang/home).

Sign in to comment on this issue.