From power-on · L0 to L4

Boot

sysk starts on the machine's first instruction, with no firmware underneath. A dozen lines of assembly hand over to sysp, which builds the kernel, prepares every task, and drops into user mode. At the end the machine turns itself off and reports whether everything went right.

Where it starts

QEMU is started with -machine virt -bios none -kernel build/sysk.elf. With no BIOS, QEMU loads the ELF into RAM at 0x8000_0000; its one hart starts in a tiny reset ROM at 0x1000 that jumps there, in machine mode, the most privileged of RISC-V's three modes. The linker script puts _start from arch/rv64/boot.S first in the image, so that is the first instruction sysk runs.

From reset to the first task, step by step

Select a step, or play the whole boot. The panel shows what the machine looks like at that moment: which mode the hart is in, whose stack it is on, whether the timer can interrupt it, which PMP entries are set, and what has appeared on the serial console.

    Mode
    Running
    Stack
    Timer
    PMP (user)
    Code

    Why it is shaped this way

    • As little assembly as possible before sysp. boot.S only makes it safe to run C: no interrupts, a trap vector, a stack, a zeroed .bss. Then it jumps to kmain, whose type is never: sysp proves it never returns, so nothing needs to catch a return.
    • All authority starts in one value. kmain receives the only Root. From it come the kernel's Console and the Halt that can stop the machine. See Capabilities.
    • Allocation happens only at boot. The kernel's buffers and every task's heap words come from the boot arena, a bump allocator in alloc.S. Nothing that runs after the first task starts has the alloc effect, and sysp checks that, so the arena is never touched again. See Memory.
    • The boot context waits underneath. run switches to task 0 and is not resumed until every task has finished. It is slot ntasks in the kernel's table of saved stack pointers, a task that never runs again until the end.

    How the machine stops

    sysk ends by writing to the SiFive test device at 0x10_0000, which makes QEMU exit with a status. The exit status is the verdict the tests read.

    StatusPrinted lastWhen
    0sysk: all tasks finishedevery task ran to its end; kmain calls halt with 0
    2sysk: panicthe boot arena ran out, or a buffer the heap never made was freed into it
    3sysk: task faulta task broke a hardware rule: a PMP violation, a privileged instruction, a gate number that does not exist
    3sysk: trapa trap in machine mode, which is a kernel bug, or an interrupt sysk does not expect

    The boot, as it prints

    The transcript from the last make docs. Lines starting sysk: are the kernel's own, written straight to the UART while no task runs; the rest come through the UART driver.