Kernel
A compact reference for the assumptions shared by the examples: AArch64 entry, exception-level descent, vectors, stacks, timer ticks, and fault reporting.
Firmware handoff
The Raspberry Pi firmware loads kernel8.img and enters AArch64 code. Alquist examples keep the boot contract small: one image, one linker script, a known stack, and explicit UART initialization before any complicated subsystem speaks.
The examples do not rely on a device tree. Board support uses known BCM2711 addresses and initializes the peripherals it needs directly.
Exception levels
QEMU and hardware may start at different exception levels. The boot code checks CurrentEL, descends when needed, sets the EL1 stack, installs the vector table, and enters kernel_main(). Later examples use EL0 for user programs, but the driver-facing kernel work lives at EL1.
Vectors and faults
A trap that loops silently is not enough. Current examples route unexpected exceptions through a C fault reporter that prints ESR, ELR, FAR, SPSR, and EC over UART before halting. This is required for hardware debugging, where a black screen and a stopped LED are otherwise indistinguishable from many unrelated failures.
Timer and scheduler
Timer IRQs drive ticks, sleeping tasks, and preemption where the example has a context-switching scheduler. Non-timer IRQs must return the stack pointer from the interrupted frame unless the scheduler deliberately switches context. That rule matters now that UART RX interrupts can arrive between timer ticks.