We’re excited to share a new feature landing in meta-pantavisor: Raspberry Pi Generic Machine support with A/B boot partitions via the RPi tryboot mechanism.
What Is It?
Until now, building a Pantavisor image for Raspberry Pi meant picking a specific model — raspberrypi-armv8 for Pi 4 64-bit, raspberrypi5 for Pi 5, and so on. The new rpi machine target builds a single SD card image that boots on every Raspberry Pi ever made, from the original Pi 0 through the Pi 5 and CM5.
The same image also brings proper A/B boot partitions, so Pantavisor can safely update the boot firmware with automatic rollback — no more bricked devices from a bad kernel update.
How It Works: Five Kernels, One Boot Partition
The Raspberry Pi bootloader auto-detects the board model and loads a specific kernel filename. We exploit this by building five kernel variants in parallel using Yocto multiconfigs and packing them all into one FAT32 boot partition:
| Kernel File | Models |
|---|---|
kernel.img |
Pi 0, 0W, 1 (ARMv6) |
kernel7.img |
Pi 2, 3 32-bit (ARMv7) |
kernel7l.img |
Pi 4 32-bit (ARMv7) |
kernel8.img |
Pi 02W, 3, 4, CM4, Pi 400 (AArch64) |
kernel_2712.img |
Pi 5, CM5 (AArch64, BCM2712) |
The config.txt uses the Pi bootloader’s [pi*] conditional sections to select the right kernel per board — no U-Boot needed. A shared Pantavisor initramfs is loaded alongside via initramfs pantavisor followkernel.
One interesting challenge: the Pi 5 kernel uses 16K page sizes while all other Pis use 4K. Since the initramfs is shared across all models, we align all ELF segments to 64K (-Wl,-z,max-page-size=65536) so the same binaries work everywhere.
A/B Boot Partitions with Tryboot
The disk layout uses four partitions:
| # | Name | Size | Purpose |
|---|---|---|---|
| 1 | bootsel | 32M | A/B selector (autoboot.txt, EEPROM firmware) |
| 2 | boot_a | 128M | Primary boot partition (kernels, DTBs, initramfs) |
| 3 | boot_b | 128M | Alternate boot partition (identical) |
| 4 | root | rest | ext4 rootfs with Pantavisor trails |
The bootsel partition contains an autoboot.txt that uses the RPi bootloader’s tryboot_a_b mode:
[all]
tryboot_a_b=1
boot_partition=2
[tryboot]
boot_partition=3
During normal operation the bootloader loads from partition 2 (boot_a). When Pantavisor stages an update, it writes to the alternate partition and triggers a tryboot — if the new version fails to confirm, the bootloader automatically falls back.
EEPROM Auto-Update
There’s a catch: the tryboot_a_b mode with correct partition numbering was only added in Pi EEPROM firmware from late 2022. Older Pi 4 and Pi 5 boards in the field may have outdated firmware.
Pantavisor now detects the EEPROM version at early boot via the VideoCore mailbox (GET_GENCMD_RESULT). If the firmware is too old, it stages an update from the bootsel partition using mtools — writing pieeprom.upd and pieeprom.sig first, then recovery.bin last (the trigger file). This ordering means a power cut mid-stage leaves the source files intact for retry. A hardware watchdog (15s) is armed before the EEPROM reboot as a safety net since Pantavisor’s watchdog subsystem isn’t initialized yet at that stage.
Per-Kernel Module Squashfs
Since each Pi model runs a different kernel version, we can’t ship a single modules.squashfs. Instead, the build produces per-kernel-version modules:
modules_6.1.77-v+.squashfs(Pi 0/1)modules_6.1.77-v7+.squashfs(Pi 2/3)modules_6.1.77-v7l+.squashfs(Pi 4 32-bit)modules_6.1.77-v8+.squashfs(Pi 3/4 64-bit)modules_6.1.77-v8-2712+.squashfs(Pi 5)
Firmware is shared across all models in a single firmware.squashfs. At runtime, Pantavisor mounts only the modules matching the running kernel.
Getting Started
Build with KAS:
kas build kas/scarthgap.yaml:kas/machines/rpi.yaml:kas/bsp-base.yaml
Flash the resulting .wic.bz2 image to an SD card and boot on any Pi. The EEPROM will auto-update if needed, and you’ll have a working Pantavisor system with A/B boot support.
The code lives in meta-pantavisor on the feature/rpi-generic-machine branch and will be merged to master soon.