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, process
creation, and QEMU halt-on-success are implemented. The current default boot
still lets the kernel interpret the whole service graph. The selected milestone
in WORKPLAN.md is to move manifest graph execution into init.
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, loads each service ELF into a fresh
AddressSpace, builds per-service capability tables and read-only CapSet
pages, enqueues the processes, and starts the scheduler.
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 --> Images[parse and map service ELFs]
Manifest --> Caps[build CapTables and CapSet pages]
Images --> Processes[create Process structs and rings]
Caps --> Processes
Processes --> Scheduler[start round-robin scheduler]
Scheduler --> User[enter first user process]
The invariant is that no user service starts until manifest binary references, authority graph structure, and bootstrap capability source/interface checks have passed.
Design
The boot path is deliberately single-shot. The kernel receives a single packed manifest and validates the graph before creating any process. ELF parsing is cached per binary name, but each service gets its own address space, 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 directly. The spawn manifest (system-spawn.cue) packages only
init as an initial service and grants it ProcessSpawner plus endpoint caps;
init then spawns selected child services.
Future behavior is narrower: the kernel should start only init with fixed
bootstrap authority and a manifest or boot-package capability. init should
validate and execute the service graph through ProcessSpawner.
Invariants
- Limine must provide exactly one boot module, and that module is the manifest.
- Manifest validation must complete before any declared service is enqueued.
- 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, service image 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- manifest capability resolution and CapSet entry construction.capos-config/src/manifest.rs- manifest decode, schema-version guardrails, and graph/source/binary validation.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 manifest, kernel-side service startup, process creation, scheduler entry, and clean QEMU halt.make run-spawnvalidates init-owned spawning throughProcessSpawnerfor the current transition path.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
- Move default service graph interpretation from the kernel into
init. - Retire kernel-side service graph wiring after default
make runproves the init-owned path.