Raspberry Pi Generic Machine: One Image for All Pi Models with A/B Boot

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.

This feature has now been merged to master!

To build the unified RPi image from master:

kas build kas/scarthgap.yaml:kas/machines/rpi.yaml:kas/bsp-base.yaml