Raspberry Pi 5
Relevant source files
- scripts/build/rpi5.sh
- scripts/deploy/rpi5.sh
- kernel/Cargo.toml
- docs/operations/boot.md
- docs/reference/generated/artifacts.md
The Raspberry Pi 5 is the primary hardware target. The kernel is built as a raw kernel8.img with the ext2 root filesystem embedded via include_bytes!, and placed on the FAT32 boot partition of an SD card.
Pi 5 testing is manual; there is no hardware-in-the-loop CI. The target manifest labels the Pi 5 supported after HIL. Treat QEMU results as preflight evidence only.
Build
Provide the trust key
The kernel embeds the production Ed25519 public key. The script refuses to generate a substitute.
export AXIOM_BPF_TRUSTED_KEY_PATH=/secure/path/axiomos-ed25519.pub
test "$(wc -c < "$AXIOM_BPF_TRUSTED_KEY_PATH")" -eq 32Build
cargo xtask build rpi5 -- release embedded-rpi5The script takes two positional arguments after --: the profile (release or debug, default release) and the kernel feature list (default embedded-rpi5). Use --dry-run before -- to print the delegated command.
Check outputs
Everything lands under target/aarch64-unknown-none/release/ (or debug):
| File | Contents |
|---|---|
kernel | Kernel ELF |
kernel8.img | Raw binary made with llvm-objcopy -O binary (or rust-objcopy) |
rpi5-artifacts.sha256 | SHA-256 of the ELF, kernel8.img, rootfs image and the trust key file |
What scripts/build/rpi5.sh does internally:
- Installs the
aarch64-unknown-nonetarget if missing. - Builds the root package with
--no-default-features --features aarch64_depsto produce the rootfs, and readsDISK_IMAGEfrom a uniqueAXIOM_ARTIFACT_PATHSfile. - Exports
AXIOM_DISK_IMAGEand builds-p kernelwith the requested features. - Converts the ELF to
kernel8.imgand writes the hash manifest.
Instrumented images
Build instrumented images separately and do not ship them as production; the kernel features are off by default:
cargo xtask build rpi5 -- release embedded-rpi5,verifier-cost # verifier-cost calibration
cargo xtask build rpi5 -- release embedded-rpi5,bench # GPIO-to-actuation timingThe bringup-diagnostics feature in kernel/Cargo.toml is a further bring-up-only option.
Deploy
Inspect first, then write to the mounted boot partition (not the host root filesystem):
cargo xtask deploy rpi5 --dry-run -- /path/to/mounted/pi-boot
cargo xtask deploy rpi5 -- /path/to/mounted/pi-boot
syncThe deploy script takes the mount point and an optional debug or release profile. It then:
- Checks that
kernel8.imgandrpi5-artifacts.sha256exist. - Runs
sha256sum -cagainst the manifest. - Copies
kernel8.imgand the manifest (asaxiomos-rpi5-artifacts.sha256) to the card. - Creates
config.txtonly if one does not already exist.
The generated config.txt contains:
| Setting | Why |
|---|---|
arm_64bit=1, kernel=kernel8.img | 64-bit boot of the kernel image |
pciex4_reset=0 | Keep RP1 peripherals initialized without a PCIe driver |
enable_rp1_uart=1 | Bare-metal UART0 at 115200 baud through RP1 |
enable_uart=1, uart_2ndstage=1 | UART output and early debug output |
disable_splash=1, gpu_mem=16 | Faster boot, minimal GPU memory |
dtoverlay=disable-bt | Bluetooth otherwise uses the UART pins |
Raspberry Pi boot firmware must already be on the SD card. This repository neither fetches nor pins it. Record its revision and hashes with any HIL evidence.
Serial console
Connect a UART debug probe, find a stable path under /dev/serial/by-id/, and capture at 115200 baud before applying power:
PORT=/dev/serial/by-id/<debug-probe-uart>
sudo timeout 120s cat "$PORT" | tr -d '\r' | tee pi5-boot.logThe kernel console is the Pi 5’s dedicated debug UART (UART10), which is what the Raspberry Pi Debug Probe attaches to. The signed_bpf_loader userspace tool prints SIGNED_BPF_LOAD_OK on a successful signed load.
Known limitations
From the README: user-mode page faults panic the kernel, no demand paging, no POSIX signals, a single global run queue, only GPIO/PWM/UART on RP1 (no I2C, SPI, CAN or Ethernet), and no hardware watchdog integration. See the repository README for the full list.