Boot Flow
Boot flow defines the trusted path from firmware-owned machine state to the first user processes. It establishes memory management, interrupt/syscall entry, capability tables, process rings, and the boot manifest authority graph.
Status: Partially implemented. Limine boot, kernel initialization, manifest parsing, ELF loading, init process creation, init-owned service graph execution, and QEMU halt-on-success are implemented. Remaining boot-flow work is post-milestone cleanup of the bootstrap manifest shape and generic kernel service-cap resolver.
Current Behavior
Firmware loads Limine, Limine loads the kernel and exactly one module, and the
kernel treats that module as a Cap’n Proto SystemManifest. The kernel rejects
boots with any module count other than one.
kmain initializes serial output, x86_64 descriptor tables, memory, paging,
SMEP/SMAP, the kernel capability table, the idle process, PIC, and PIT. It then
parses and validates the manifest, requires config.initExecutesManifest, loads
only the first init service ELF into a fresh AddressSpace, builds init’s
bootstrap capability table and read-only CapSet page, enqueues init, and starts
the scheduler. Init reads the BootPackage manifest, validates the service graph,
spawns child services through ProcessSpawner, and waits for them.
flowchart TD
Firmware[UEFI or QEMU firmware] --> Limine[Limine bootloader]
Limine --> Kernel[kmain]
Limine --> Module[manifest.bin boot module]
Kernel --> Arch[serial, GDT, IDT, syscall MSRs]
Kernel --> Memory[frame allocator, heap, paging, SMEP/SMAP]
Kernel --> Manifest[parse and validate SystemManifest]
Manifest --> InitImage[parse and map init ELF]
Manifest --> InitCaps[build init CapTable and CapSet page]
InitImage --> InitProcess[create init Process and ring]
InitCaps --> InitProcess
InitProcess --> Scheduler[start round-robin scheduler]
Scheduler --> Init[enter init]
Init --> BootPackage[read BootPackage manifest]
Init --> Spawner[spawn child services]
Spawner --> Children[default demo processes]
The invariant is that no child service starts until manifest binary references, authority graph structure, and bootstrap capability source/interface checks have passed in both the kernel bootstrap validation and init’s metadata-only BootPackage validation.
Design
The boot path is deliberately single-shot. The kernel receives a single packed
manifest and validates the graph before creating init. Init then performs the
userspace execution step: it reads manifest chunks from BootPackage, validates a
metadata-only ManifestBootstrapPlan, resolves kernel and service cap sources,
and asks ProcessSpawner to load each child ELF into its own address space with
its own user stack, TLS mapping if present, ring page, and CapSet mapping.
The default manifest (system.cue) packages init, capos-rt-smoke, and the
demo services, but sets config.initExecutesManifest. The kernel rejects
manifests that omit that flag. The spawn manifest (system-spawn.cue) is a
narrower init-owned graph retained for focused ProcessSpawner validation.
Invariants
- Limine must provide exactly one boot module, and that module is the manifest.
- Kernel manifest validation must complete before init is enqueued, and init BootPackage validation must complete before any child service is spawned.
- Service ELF load failures roll back frame allocations before boot continues or fails.
- Kernel page tables are active and HHDM user access is stripped before SMEP/SMAP are enabled.
- The kernel passes
_start(ring_addr, pid, capset_addr)in RDI, RSI, and RDX. - CapSet metadata is read-only user memory; the ring page is writable user memory.
- QEMU-feature boots halt through
isa-debug-exitwhen no runnable processes remain.
Code Map
kernel/src/main.rs-kmain, manifest module handling, validation, boot-only-init loading, process enqueue, halt path.kernel/src/spawn.rs- ELF-to-address-space loading, fixed user stack, TLS mapping,Processconstruction helpers.kernel/src/process.rs- process bootstrap context, ring page mapping, CapSet page mapping.kernel/src/cap/mod.rs- bootstrap capability resolution and CapSet entry construction for init.capos-config/src/manifest.rs- manifest decode and schema-version storage.capos-config/src/validation.rs- graph/source/binary validation policy.tools/mkmanifest/src/lib.rs- host-side manifest validation and binary embedding.system.cueandsystem-spawn.cue- default and spawn-focused boot graphs.limine.confandMakefile- bootloader config, ISO construction, QEMU targets.
Validation
make runvalidates the default init-owned manifest executor, init BootPackage reads, ProcessSpawner child startup, child waits, and clean QEMU halt.make run-spawnvalidates the narrower init-owned ProcessSpawner smoke.cargo test-configcovers manifest decode, roundtrip, and validation logic.cargo test-mkmanifestcovers host-side manifest conversion and embedding checks.make generated-code-checkverifies checked-in Cap’n Proto generated output.
Open Work
- Retire the remaining generic kernel service-cap resolver now that the default boot path no longer uses kernel-side service graph wiring.