boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

amd64 seed-kernel TODO

Working doc. Captures the tcc 0.9.26 limitations we worked around to bring up boot6 amd64 and DRIVER=seed ./scripts/boot.sh amd64, plus what's still unvalidated. Pairs with docs/OS.md (kernel contract), docs/TCC.md (compiler), and docs/SEED-RISCV64-TODO.md (parallel write-up for the riscv64 path).

Goal

DRIVER=seed ./scripts/boot.sh amd64 should run the full boot0→boot6 chain entirely inside the tcc-built amd64 seed kernel (the kernel is its own build driver, podman only mints the first kernel image). This validates every kernel path the chain depends on under real workloads.

What works (May 2026)

tcc 0.9.26 limitations worked around for amd64

These are amd64-specific gotchas; the existing docs/TCC.md and the simple-patches in scripts/simple-patches/tcc-0.9.26/ cover the shared/aarch64/riscv64 issues.

  1. .quad literal truncation. tcc's assembler silently truncates a .quad value to its low 32 bits when the high half is non-zero (gen_le64(int64_t c) is fed a value already lost through the parser path). The amd64 GDT entries (0x00af9a000000ffff, 0x00af92000000ffff) are the natural trip wire — without the workaround, the bootloader's lgdt loads zero P/L bits, the long-mode ljmp raises #GP, and the kernel never prints anything.

    • Workaround: seed-kernel/arch/amd64/kernel.S encodes each descriptor as .long lo, hi so the high half is parsed as a fresh 32-bit literal. Comment in-place explains why.
    • TODO: add a simple-patch to fix .quad parsing in tccasm.c so the source can use the natural form. Suspected site is the parser path that intermediates 64-bit values through a 32-bit int before reaching gen_le64.
  2. No PT_NOTE program header / SHT_NOTE section type. tcc's linker emits exactly two PT_LOAD phdrs for static EXEs (no PT_NOTE), and find_section defaults every assembler-created section to SHT_PROGBITS regardless of name. QEMU's PVH -kernel path scans PT_NOTE phdrs for the Xen 18 note that names the 32-bit entry; without one it errors out with "Error loading uncompressed kernel without PVH ELF Note".

    • Workaround: seed-kernel/scripts/elf-pvh-note.c is a tiny tcc-built post-link tool that locates .note.Xen via the section header table, retypes the section as SHT_NOTE, and writes a fresh PT_NOTE phdr at phoff + phnum*phentsize (the gap between Ehdr/Phdrs and the first PT_LOAD's content at offset s_align = 0x200000 has plenty of room). Wired into boot6-gen-runscm.sh and boot6.sh for amd64 only.
    • TODO: patch tcc to (a) detect ".note.*" section names and create them as SHT_NOTE, and (b) bump phnum + emit PT_NOTE phdrs for each SHT_NOTE alloc section after layout_sections. That removes the need for the post-link tool.

amd64 kernel additions (not tcc workarounds)

These are real kernel features that aarch64/riscv64 already had in some form and amd64 was missing. Listing them so the riscv64-style TODO has full context, not because they're broken.

What's not yet validated

  1. boot3 → boot6 under DRIVER=seed amd64. boot3 (scheme1 driving cc.scm to compile tcc.flat.c + libc.flat.c → tcc0) is compute-bound under TCG-emulated x86_64 on Apple Silicon (no hvf for amd64). The aarch64 path uses hvf and runs at near-native speed; amd64 is 5–20× slower. Concretely: boot3 timed out at the previous 1800 s default. We bumped the timeout knob (BOOT3_TIMEOUT, BOOT4_TIMEOUT) and a 4 h boot3 run is in progress — see build/amd64/.boot3-stage/ transcript.txt for the live log.
  2. Fixed-point check. Once boot3/4/5 complete, the artifacts (catm/scheme1/tcc0/tcc1/tcc2/tcc3/libc.a/...) should byte-match the DRIVER=podman amd64 outputs. Untested.
  3. scripts/run-tests.sh amd64 under DRIVER=seed. Untested.
  4. boot4's tcc fixed-point assertion (tcc2 == tcc3) under DRIVER=seed amd64. Untested.

Cost / acceleration note

The amd64 seed driver runs under qemu-system-x86_64 -cpu max with TCG (no hvf for x86_64 on Apple Silicon). A full DRIVER=seed scripts/boot.sh amd64 is realistically a multi-hour operation. The aarch64 path is the fast/CI iterating loop; the amd64 seed path is mostly there for parity validation.