Seed kernel — open items
The OS.md contract is fully met by seed-kernel/:
boots via the arm64 Linux boot protocol, parses the DTB, unpacks an
initramfs into an in-memory tmpfs, loads /init as a static aarch64
ELF, dispatches the eight Tier-1 syscalls plus atomic sys_spawn
(private syscall 1024, replaces POSIX clone+execve) and
sys_waitid, with virtio-blk in/out transports for boot{0..5} use.
scripts/tier1-gate.sh and
scripts/tier2-gate.sh cover
acceptance; boot{0..5}.sh DRIVER=seed is byte-identical to the
podman path. HVF acceleration enabled.
This file tracks remaining polish.
tcc3 self-host of seed-kernel/
The C side already compiles and runs cleanly under
build/aarch64/boot4/tcc3 — kernel.c and
user/{forktest,child,hello}.c have no inline asm, all sysreg / barrier
/ cache / TLB / PSCI ops route through the C-callable thunks at the
bottom of kernel.S, and per-syscall
wrappers delegate to a single syscall6 toplevel-asm thunk.
Remaining blockers are all in tcc 0.9.26's arm64 assembler /
linker (see docs/TCC-ARM64-ASM.md for the
phase-1/2/3 trajectory of
scripts/simple-patches/tcc-0.9.26/files/arm64-asm.c).
kernel.S mnemonics not yet in phase-2
msr/mrsto/from named system registers:mair_el1,tcr_el1,ttbr0_el1,sctlr_el1,cpacr_el1,sp_el0,esr_el1,far_el1,vbar_el1,hcr_el2,spsr_el2,elr_el2,sp_el1. Plus the immediate / pseudo formsmsr daifset, #immandmrs CurrentEL.eret.ic iallu,tlbi vmalle1.dsb sy/dsb ish/dmb ish/dmb ishstby name — the current assembler wantsdsb #immand rejects the named scope.adrp/adr+:lo12:relocations for label addresses (the EL1 boot path usesadrp Xn, sym; add Xn, Xn, :lo12:sym)..macro/.endm(VENTRY pattern in the exception vector table)..quad sym1 - sym2(the arm64 Image header'simage_sizefield).
kernel.lds — no -T in tcc3
tcc3's linker accepts -Wl,-Ttext=, -Wl,-image-base=,
-Wl,-section-alignment= only; there is no -T script. The seed
kernel's link layout needs:
KEEP(*(.head.text))placed first (boot header at0x40080000).- Link-time symbol assignments:
__bss_start,__bss_end,kstack_top,_end,_image_end. - A custom
.stacksection sized to 64 KB.
Two paths: tcc gains a small ld-script subset, or kernel.S
self-defines the symbols and reserves stack space inline (with
-Wl,-Ttext=0x40080000 replacing the base). The former is bigger
but reusable across kernel-style targets; the latter ties section
ordering to input file order and is brittle.
Toplevel asm() .globl ordering — worked around
tcc 0.9.26's toplevel-asm parser leaves a symbol marked UND if
.globl name precedes name:; the reverse order registers it as
defined (gcc accepts both). Worked around in user/{forktest, child,hello}.c with label: first and .globl label immediately
after, with a sourcecode comment noting the constraint. A tcc-side
fix would let the comments go.
Open polish
NULL-page hardening. Slot 0 is unmapped so a NULL deref faults to the kernel as a user sync; the kernel currently panics rather than delivering a SIGSEGV-equivalent. Acceptable per OS.md (default-action termination is sufficient) but a minor polish opportunity.
Cache parsed prelude in kernel. Each spawn re-parses the 24 KB
prelude.scmfrom scratch. Hashing it once and reusing the AST across spawns would shave a fraction of per-spawn overhead. Not load-bearing now that sys_spawn removed the big copy; would matter again if a future driver crosses ~10k spawns.