Build System
meta-pantavisor is the Yocto/OpenEmbedded layer that builds Pantavisor-based BSP images for embedded Linux products. It provides recipes, BitBake classes, and KAS configurations for producing initramfs images and container pvrexport bundles. For the build workflow itself, see Get started.
Key Directories
meta-pantavisor/
├── classes/ # BitBake classes
├── conf/ # Layer and distro configuration
│ └── multiconfig/ # Per-multiconfig TMPDIR settings
├── dynamic-layers/ # Conditional recipes for other layers
├── kas/ # KAS configuration fragments
│ ├── build-configs/ # One-file release build configs
│ ├── machines/ # Per-machine configurations
│ └── platforms/ # Platform-specific layer includes
├── recipes-containers/
│ └── pv-examples/ # Example containers for xconnect testing
├── recipes-pv/ # Core pantavisor recipes
│ ├── images/ # Appengine and BSP image recipes
│ ├── pantavisor/ # Pantavisor runtime
│ └── pvr/ # PVR tool
├── recipes-devtools/ # Development tools (json-sh, fdisk)
└── wic/ # WIC disk image layout files
Key Recipes
| Recipe | Description |
|---|---|
recipes-pv/pantavisor/pantavisor_git.bb | Core Pantavisor runtime (C, cmake-based); SRCREV forwarded from pantavisor.inc |
recipes-pv/images/pantavisor-initramfs.bb | Initramfs image |
recipes-pv/images/pantavisor-bsp.bb | BSP image (generates pvrexport bundles) |
recipes-pv/images/pantavisor-starter.bb | Flashable starter disk image (.wic) |
recipes-pv/pvr/pvr_*.bb | PVR CLI tool (Go-based) |
recipes-pv/lxc-pv/lxc-pv_git.bb | Pantavisor-specific LXC fork |
BitBake Classes
| Class | Description |
|---|---|
classes/pvbase.bbclass | Defines PANTAVISOR_FEATURES variable and defaults |
classes/pvrexport.bbclass | PVR export functionality for images |
classes/container-pvrexport.bbclass | Container pvrexport packaging |
classes/pvr-ca.bbclass | Certificate authority handling |
classes/pvroot-image.bbclass | Root container image support |
KAS Configuration Hierarchy
KAS is the primary build system. Configuration is composed by layering YAML fragments:
| File | Description |
|---|---|
kas/bsp-base.yaml | Base configuration for BSP builds; defines repos and core settings |
kas/bsp-multi.yaml | Multiconfig builds (separate configs for initramfs and containers) |
kas/scarthgap.yaml / kas/kirkstone.yaml | Yocto release-specific patches and branches |
kas/machines/*.yaml | Per-machine configurations |
kas/platforms/*.yaml | Platform-specific layer includes (sunxi, raspberrypi, etc.) |
kas/with-workspace.yaml | Overlay for local pantavisor source development |
Build configs
kas/build-configs/ holds the build configs you pass to kas build directly.
The release/ ones pin a machine and are self-contained. The build-base-*
ones are minimal bases (image target + a couple of features) that expect a
machine fragment prepended, as in .github/machines.json. kas menu does not
use these files — it writes its own .config.yaml from Kconfig, including the
pantavisor-starter + pv-flash-bundle (± recovery multiconfig) target set for
factory-flash machines via the "Also build pv-flash-bundle" prompt.
| Config | Machine | Target |
|---|---|---|
build-base-starter.yaml | (from kas menu) | pantavisor-starter |
build-base-remix.yaml | (from kas menu) | pantavisor-remix |
build-appengine-distro.yaml | (from kas menu) | pantavisor-appengine-distro |
release/96boards-orangepi-i96-scarthgap.yaml | orangepi-i96 | pantavisor-starter |
release/colibri-imx6ull-scarthgap.yaml | colibri-imx6ull | pantavisor-starter |
release/docker-armv8-scarthgap.yaml | docker-armv8 | pantavisor-appengine-distro |
release/docker-x86_64-scarthgap.yaml | docker-x86_64 | pantavisor-appengine-distro |
release/imx8mm-var-dart-scarthgap.yaml | imx8mm-var-dart | pantavisor-starter |
release/imx8mn-var-som-scarthgap.yaml | imx8mn-var-som | pantavisor-starter |
release/imx8qxp-b0-mek-scarthgap.yaml | imx8qxp-b0-mek | pantavisor-starter |
release/radxa-rock5a-scarthgap.yaml | rock-5a | pantavisor-starter |
release/raspberrypi-armv8-scarthgap.yaml | raspberrypi-armv8 | pantavisor-starter |
release/rockchip-orangepi-5b-scarthgap.yaml | orangepi-5b | pantavisor-starter |
release/rpi-scarthgap.yaml | raspberrypi | pantavisor-starter |
release/sunxi-bananapi-m2-berry-scarthgap.yaml | bananapi-m2-berry | pantavisor-starter |
release/sunxi-orange-pi-3lts-scarthgap.yaml | orange-pi-3lts | pantavisor-starter |
release/sunxi-orange-pi-r1-scarthgap.yaml | orange-pi-r1 | pantavisor-starter |
release/verdin-imx8mm-scarthgap.yaml | verdin-imx8mm | pantavisor-starter |
The release/*.yaml Target column shows pantavisor-starter, but the
factory-flash machines also build pv-flash-bundle (and, for Toradex, the
mc:tezi-recovery:u-boot-toradex multiconfig). Those extras are declared per
machine as extra_targets in .github/machines.json and appended to the
target: list by .github/scripts/makemachines — there is no dedicated
build-base-*-starter.yaml for them.
Multiconfig Architecture
When using bsp-multi.yaml, builds use three separate multiconfigs to avoid TMPDIR conflicts:
| Multiconfig | Purpose | Config file |
|---|---|---|
default | Main image build | — |
pv-initramfs-panta | Initramfs with musl libc | conf/multiconfig/pv-initramfs-panta.conf |
pv-panta | Container builds | conf/multiconfig/pv-panta.conf |
Each multiconfig uses a separate TMPDIR, set in its conf file:
# conf/multiconfig/pv-initramfs-panta.conf
TMPDIR = "${TOPDIR}/tmp-${DISTRO_CODENAME}-pv-initramfs-panta"
# conf/multiconfig/pv-panta.conf
TMPDIR = "${TOPDIR}/tmp-${DISTRO_CODENAME}-pv-panta"
(Only the Raspberry Pi kernel-variant multiconfigs append ${MACHINE} — see below.)
PANTAVISOR_FEATURES
Controls which optional Pantavisor components are compiled in and installed. Defined in classes/pvbase.bbclass. The table below lists the commonly used features, not an exhaustive set:
| Feature | Description |
|---|---|
dm-crypt | Storage encryption |
dm-verity | Container rootfs integrity verification |
autogrow | Automatic partition growing |
runc | OCI runtime support |
tailscale | Tailscale VPN integration |
debug | Debug features |
pvcontrol | pv-ctrl socket and CLI tools (pvcurl, pvcontrol) |
xconnect | Service mesh for container-to-container communication |
xconnect-dbus-systembus | D-Bus system bus support for xconnect |
container-mdev | Per-container mdev device-node hook (runs an mdev LXC mount hook on each container start) |
rngdaemon | Random number generator daemon |
squash-lz4 | LZ4 squashfs compression |
squash-zstd | Zstd squashfs compression |
rpi-tryboot | Raspberry Pi A/B boot partition support |
bootchartd | Boot timing analysis (writes to /; use rdinit=/sbin/bootchartd) |
lxc-next | LXC 6.x (lxc6-pv) instead of the default LXC 3.x (lxc-pv); also available as the kas/with-lxc-next.yaml fragment |
wakelocks | PM wakelocks + autosleep — adds the wakelock.cfg kernel fragment (see pantavisor wakelocks) |
console-logging | Boot console logging on Raspberry Pi images |
automod | Automatic kernel module loading (kmod in the initramfs) |
caam-nxp | NXP CAAM secure key support (caam-nxp.cfg kernel fragment, keyctl-caam) |
dcp | NXP DCP hardware-bound trusted keys (i.MX6ULL kernel patches, keyutils) |
debug-hooks | Debug hook scripts (-DPANTAVISOR_DEBUG_HOOKS=ON) |
appengine | Container-hosted appengine build (-DPANTAVISOR_APPENGINE=ON); appended by the panta-appengine distro |
pv-manifest-audit / pv-manifest-strict | Manifest audit of the built image; strict fails the build on a mismatch |
Default: dm-crypt dm-verity autogrow runc tailscale debug rngdaemon pvcontrol xconnect xconnect-dbus-systembus container-mdev
Caution:
rngdaemonappears in the default string, but nothing in the layer gates on that token —pantavisor-initramfs.bbchecks for a feature namedrngdinstead. Appendrngdexplicitly if you need the RNG daemon.
The += vs :append Pitfall
pvbase.bbclass sets defaults via ??= (weak default operator):
PANTAVISOR_FEATURES ??= " dm-crypt dm-verity autogrow runc tailscale debug rngdaemon pvcontrol xconnect xconnect-dbus-systembus container-mdev "
In distro includes, you must use :append or :remove — never +=:
# WRONG — clobbers ??= defaults, silently drops xconnect, pvcontrol, rngdaemon
PANTAVISOR_FEATURES += "appengine"
# CORRECT — preserves ??= defaults and appends
PANTAVISOR_FEATURES:append = " appengine"
Raspberry Pi Tryboot (rpi-tryboot)
The rpi-tryboot feature enables A/B boot partition support for Raspberry Pi, building a unified boot image supporting all RPi variants from a single build.
Configuration: kas/machines/rpi.yaml
Kernel Variant Multiconfigs
| Multiconfig | Machine | Target |
|---|---|---|
rpi-kernel.conf | raspberrypi | Pi 0/1 |
rpi-kernel7.conf | raspberrypi2 | Pi 2/3 32-bit |
rpi-kernel7l.conf | raspberrypi-armv7 | Pi 4 32-bit |
rpi-kernel8.conf | raspberrypi-armv8 | Pi 3/4 64-bit |
rpi-kernel_2712.conf | raspberrypi5 | Pi 5 |
Each uses a separate TMPDIR: tmp-${DISTRO_CODENAME}-rpi-kernel-${MACHINE}.
Key Recipes
dynamic-layers/meta-raspberrypi/recipes-pv/images/rpi-boot-image.bb— FAT32 boot partition with all kernel variantsdynamic-layers/meta-raspberrypi/recipes-pv/images/rpi-bootsel.bb— Boot selector partition withautoboot.txt- WKS file:
wic/rpi-tryboot-ab.wks
Partition Layout
Partition 1 (bootsel): FAT16 — autoboot.txt, bootcode.bin (A/B selector)
Partition 2 (boot_a): FAT32 — kernels, DTBs, config.txt, initramfs
Partition 3 (boot_b): FAT32 — same as boot_a (for A/B switching)
Partition 4 (root): ext4 — rootfs with /trails/0 pvr state
Output Artifacts
These are packed into the bsp/ directory of the BSP pvrexport state (by
pantavisor-bsp.bb), not shipped as standalone deploy files:
pantavisor-rpi.img.gz— Gzipped boot partitionmodules_<version>.squashfs— Per-kernel-version modules (e.g.modules_6.6.63-v8+.squashfs)firmware.squashfs— Shared firmware
Output Artifacts
Build outputs are in build/tmp-{codename}/deploy/images/{machine}/:
| Artifact | Description |
|---|---|
*.pvrexport.tgz | Pantavisor export bundles (main deployment artifact) |
*.wic / *.wic.bz2 | Complete disk images |
pantavisor-initramfs-*.cpio.gz | Initramfs image |
pantavisor-appengine-docker.tar | Docker image for manual appengine testing |
pantavisor-appengine-distro-docker-x86_64-*.tar.gz | Self-contained test bundle: Docker images + test.docker.sh runner |
Supported Yocto Releases
| Release | Status |
|---|---|
| scarthgap | Primary (CI-tested) |
| kirkstone | Supported (LTS) |
Both scarthgap and kirkstone are Yocto LTS releases.
Layer compatibility is declared in conf/layer.conf:
LAYERSERIES_COMPAT_meta-pantavisor = "kirkstone scarthgap"
Key Build Paths
| Path | Description |
|---|---|
build/workspace/sources/pantavisor/ | Pantavisor source (workspace builds) |
build/tmp-scarthgap/deploy/images/ | Build outputs |
recipes-containers/pv-examples/ | Example container recipes |
kas/build-configs/release/ | KAS release machine configurations |