Exit bar: bsp-pi4 boots on a real Pi 4 at feature parity with bsp-qemu-virt — all of Phase A / B / C features work on hardware.
Scope: A second BSP (bsp-pi4) with its own reset, UART, timer, GIC-400, MMU setup; a DTB parser (tyrne-dt) so the kernel learns board topology at runtime; SD-card boot. HAL traits that worked for QEMU continue to work; differences are isolated to the BSP.
Out of scope: Pi-specific drivers beyond what the kernel needs to boot (those belong in Phase E's driver model); Wi-Fi (blob-dependent, deferred); multi-core on Pi (may drop in naturally if C was done first).
A new BSP crate that compiles for aarch64-unknown-none and provides a minimal reset path. No HAL impls yet; just the shell.
- ADR-0042 — Pi 4 boot flow. Load address under Pi firmware (
kernel_addressinconfig.txt); Pi firmware's initial CPU mode; whatconfig.txtsettings Tyrne expects. - New crate
bsp-pi4/with its ownCargo.toml,build.rs,linker.ld,boot.s,main.rs,console.rs— mirroringbsp-qemu-virtstructure. - Pi firmware interaction —
config.txtdocumentation and the expected load / entry addresses. - Placeholder main that just spins in
wfe; no console yet (D3 adds that).
- ADR-0042 Accepted.
cargo build --target aarch64-unknown-none -p tyrne-bsp-pi4produces an ELF.config.txtexample committed alongside.
Pi 4 uses GIC-400 (a GICv2 implementation). The IrqController impl differs from bsp-qemu-virt's GICv2 only in base addresses and board specifics — QEMU virt is GICv2, Pi 4 is GIC-400 (also GICv2); no IOMMU in v1, per ADR-0036.
- ADR-0043 — GIC-400 register layout. Distributor / CPU-interface base addresses on BCM2711; register offsets used; which features are used vs. ignored.
IrqControllerimpl inbsp-pi4/src/irq.rs.- Tests — host-side register layout; the real verification is D8 on hardware.
IrqControllertrait is implemented for Pi 4.- Implementation compiles and passes host-side layout tests.
Pi 4 has both a mini-UART and a PL011 (UART0). We use the PL011 for diagnostic output, with the board-specific baud-rate init that QEMU skipped.
- ADR-0044 — Pi 4 console choice. PL011 vs. mini-UART; which pins; what baud rate; whether GPIO pin-muxing is part of the BSP or out of scope.
- PL011 init sequence — baud-rate register programming (QEMU's PL011 is pre-initialized; Pi's is not).
Consoleimpl inbsp-pi4/src/console.rsusing the same trait asbsp-qemu-virtwith the Pi-specific init.- Tests — host-side: none meaningful (hardware behaviour); D7 exercises it on real hardware.
- ADR-0044 Accepted.
Consoleimpl compiles; the first real-hardware smoke will validate it.
The generic timer works like on QEMU; the difference is the frequency (from CNTFRQ_EL0) and any Pi-specific interrupt routing.
Timerimpl inbsp-pi4/src/timer.rs, readingCNTFRQ_EL0for frequency.- Interrupt-line number for the timer IRQ on Pi 4 (PPI, line number per BCM2711).
- Tests — parity with
bsp-qemu-virtwhere possible.
Timerimpl compiles; frequency reporting is correct when tested on hardware (D7 / D8 validation).
MMU activation on Pi 4. Memory layout is different (RAM at 0x0000_0000 on Pi vs. 0x4000_0000 on QEMU); peripherals at high addresses.
- ADR-0045 — Pi 4 memory layout. Kernel load address; peripheral window (
0xFE00_0000class on BCM2711); identity vs. high-half choices here. Mmuimpl — inherits VMSAv8 from QEMU's impl; differences in the linker script and the MMIO mapping tables.- Cache maintenance — Pi 4 specifics (cache lines, I/D separation, which invalidate sequences are necessary).
- Tests — B2's test suite applied to Pi 4.
- ADR-0045 Accepted.
- Kernel runs with the MMU on on Pi 4.
A userspace-agnostic library crate that parses a flattened device tree into a typed structure. Used by the BSP at boot to read what the firmware told it about the machine.
- ADR-0046 — DTB parsing scope. Full FDT spec support vs. a minimal read-only subset; zero-copy vs. owned parsing; allocation strategy (probably
no_std + allocwith an arena). - New crate
tyrne-dt/— separate fromtyrne-halso BSPs opt in. - Parser API —
DeviceTree::from_bytes(ptr) -> Result<DeviceTree, Error>; iterators over nodes; property lookup. - Pi 4 integration —
kernel_entryparses the DTB passed inx0and emits aBootInfostruct. - Host tests — parse known fixtures (QEMU-generated DTB, Pi 4 DTB samples).
- ADR-0046 Accepted.
tyrne-dtparses a real DTB into typed records.bsp-pi4uses it at boot; the kernel'sBootInfocontains at least memory-map and UART-address entries read from the DTB.
The kernel image, along with firmware, config.txt, and any boot files, is placed on an SD card; the Pi 4 boots from that card.
- Image packaging — a script in
tools/that produces ansdcard/directory (or a.imgfile) ready to be written withdd. - First real-hardware boot — runs the D3 console output; the maintainer sees the kernel greeting on a USB-UART cable.
- Guide —
docs/guides/boot-pi4.mdwalking through building, writing to SD, connecting UART, booting.
- Kernel prints its greeting on Pi 4 hardware via the PL011 UART.
- Guide is reproducible.
All Phase A / B / (C if done) features work on Pi 4 as they do on QEMU virt.
- Run the two-task IPC demo (A6) on Pi 4.
- Run the first userspace "hello" (B6) on Pi 4.
- If Phase C is done: preemption and multi-core IPC on Pi 4.
- Business review.
- A6 / B6 (and C5 if applicable) produce the expected traces on real Pi 4 hardware.
- Review records any hardware-specific learnings for future BSPs.
Business review; the phase is the most significant in terms of validating that "portable code" claim. Phase E (driver model) follows.
| ADR | Purpose | Expected state | Note |
|---|---|---|---|
| ADR-0042 | Pi 4 boot flow | D1 | renumbered 2026-05-22, was ADR-0032 (collided with the live Accepted ADR-0032 endpoint-rollback-and-cancel-recv; Phase D shifted above Phase C's new ceiling) |
| ADR-0043 | GIC-400 register layout | D2 | renumbered 2026-05-22, was ADR-0033 (reserved by phase-b.md §B5 ledger for the kernel high-half migration) |
| ADR-0044 | Pi 4 console choice (PL011 vs. mini-UART) | D3 | renumbered 2026-05-22, was ADR-0034 (reserved by phase-b.md §B5 ledger for kernel-image section permissions) |
| (none) | D4 — ARM generic timer on Pi 4 | D4 | implementation-only milestone; the generic-timer behaviour and the Timer trait are already settled by ADR-0010, so D4 requires no new ADR. The ledger jumps D3 → D5 for this reason. |
| ADR-0045 | Pi 4 memory layout | D5 | renumbered 2026-05-22, was ADR-0035 (collided with the live Accepted ADR-0035 physical-memory-manager) |
| ADR-0046 | DTB parsing scope | D6 | renumbered 2026-05-22, was ADR-0036 (avoids the ADR-0036 supersession slot reserved for the GICv2/no-IOMMU decision) |
Numbers are tentative; final numbers are assigned when the ADR is actually written, per ADR-0013.
- Whether we target Pi 4 rev 1.4 specifically or accept a range.
- USB-to-TTL cable model the guide assumes (community standards).
- SD-image composition including the Pi's closed-source firmware blobs. Resolved per ADR-0004: closed-source blobs that sit below the kernel (e.g., the VC4 stage-0 firmware on Pi 4) are out of our blob-policy scope. The SD image may therefore include them when that is the only way to boot the hardware.