Raspberry Pi 5 switched to Cortex-A76 cores and moved I/O to the RP1 southbridge chip. Building with Yocto requires more than just changing the MACHINE name from RPi4.
This guide walks through building a headless Raspberry Pi 5 image with Wi-Fi using Yocto Scarthgap 5.0 LTS. It covers the U-Boot compatibility issue, Wi-Fi driver workarounds, and known pitfalls.
What Changed in RPi5
RPi5 has a fundamentally different architecture from RPi4. Here's what matters for Yocto builds.
| Feature | RPi 4 (BCM2711) | RPi 5 (BCM2712) |
|---|---|---|
| CPU core | Cortex-A72 @ 1.8 GHz | Cortex-A76 @ 2.4 GHz |
| Process | 28nm | 16nm |
| GPU | VideoCore VI | VideoCore VII |
| I/O architecture | Integrated in SoC | RP1 southbridge (PCIe x4) |
| PCIe | None | PCIe 2.0 x1 (FPC connector) |
| USB 3.0 | Shared bandwidth | 5 Gbps per port |
| Power | 5V/3A | 5V/5A (USB-PD) |
The biggest change is the RP1 southbridge. On RPi4, Ethernet, USB, and GPIO were integrated into the SoC. On RPi5, these are handled by the RP1 chip connected via PCIe x4. This means different device trees and driver configurations. For RPi3 or RPi4, see the RPi build guide.
Setting Up the Build Environment
Host preparation
Ubuntu 24.04 LTS recommended. Install required packages.
sudo apt update
sudo apt install -y gawk wget git diffstat unzip texinfo gcc build-essential \
chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils \
iputils-ping python3-git python3-jinja2 python3-subunit zstd liblz4-tool \
file locales libacl1
sudo locale-gen en_US.UTF-8
Clone Poky and meta-layers
mkdir -p ~/yocto && cd ~/yocto
git clone -b scarthgap git://git.yoctoproject.org/poky
git clone -b scarthgap git://git.openembedded.org/meta-openembedded
git clone -b scarthgap git://git.yoctoproject.org/meta-raspberrypi
git clone -b scarthgap/u-boot https://git.yoctoproject.org/meta-lts-mixins
meta-raspberrypi uses the scarthgap branch. meta-lts-mixins uses the scarthgap/u-boot branch. The next section explains why this latter layer is needed.
Configure bblayers.conf
source poky/oe-init-build-env build-rpi5
Add layers to conf/bblayers.conf.
# conf/bblayers.conf
BBLAYERS ?= " \
/home/user/yocto/poky/meta \
/home/user/yocto/poky/meta-poky \
/home/user/yocto/poky/meta-yocto-bsp \
/home/user/yocto/meta-openembedded/meta-oe \
/home/user/yocto/meta-openembedded/meta-python \
/home/user/yocto/meta-openembedded/meta-networking \
/home/user/yocto/meta-raspberrypi \
/home/user/yocto/meta-lts-mixins \
"
The U-Boot Problem and Fix
Why meta-lts-mixins is needed
Scarthgap ships U-Boot v2024.01 by default. RPi5 support was first added in U-Boot v2024.04. The default Scarthgap U-Boot simply doesn't work on RPi5.
meta-lts-mixins (branch scarthgap/u-boot) backports U-Boot v2024.04 into Scarthgap. Adding this layer makes U-Boot boot correctly on RPi5.
Alternative: direct kernel boot
You can skip U-Boot entirely and boot the kernel directly from RPi5's firmware. However, U-Boot provides flexibility for network boot, A/B partition switching, and other features. Unless you have a specific reason to avoid it, use meta-lts-mixins with U-Boot.
Build Configuration
Basic settings
# conf/local.conf
MACHINE = "raspberrypi5"
# Place sstate-cache and downloads outside the build directory
SSTATE_DIR = "/home/user/yocto/sstate-cache"
DL_DIR = "/home/user/yocto/downloads"
For sstate-cache optimization details, see the build speed optimization guide.
Enable systemd
For headless operation, use systemd as the init manager.
# conf/local.conf
DISTRO_FEATURES:append = " systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED:append = " sysvinit"
VIRTUAL-RUNTIME_init_manager = "systemd"
VIRTUAL-RUNTIME_initscripts = "systemd-compat-units"
For creating custom systemd services, see the systemd service guide.
Wi-Fi configuration
Getting Wi-Fi working on RPi5 requires explicitly adding kernel modules and firmware.
# conf/local.conf — enable Wi-Fi
MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS += "kernel-module-brcmfmac"
MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS += "kernel-module-brcmfmac-wcc"
IMAGE_INSTALL:append = " wireless-regdb-static"
IMAGE_INSTALL:append = " wpa-supplicant"
brcmfmac-wcc is a dependency module for the Broadcom Wi-Fi driver. Without it, the Wi-Fi interface won't be detected. wireless-regdb-static provides the wireless regulatory database for your country.
Bake Wi-Fi credentials into the image
Use a bbappend to include wpa_supplicant configuration at build time.
# meta-mylayer/recipes-connectivity/wpa-supplicant/wpa-supplicant_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " file://wpa_supplicant-wlan0.conf"
do_install:append() {
install -d ${D}${sysconfdir}/wpa_supplicant/
install -m 0600 ${WORKDIR}/wpa_supplicant-wlan0.conf \
${D}${sysconfdir}/wpa_supplicant/wpa_supplicant-wlan0.conf
}
# meta-mylayer/recipes-connectivity/wpa-supplicant/files/wpa_supplicant-wlan0.conf
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
update_config=1
country=US
network={
ssid="YOUR_SSID"
psk="YOUR_PASSWORD"
key_mgmt=WPA-PSK
}
Configure systemd-networkd for Wi-Fi
# meta-mylayer/recipes-core/systemd/systemd_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " file://wlan0.network"
do_install:append() {
install -d ${D}${sysconfdir}/systemd/network/
install -m 0644 ${WORKDIR}/wlan0.network \
${D}${sysconfdir}/systemd/network/wlan0.network
}
# meta-mylayer/recipes-core/systemd/files/wlan0.network
[Match]
Name=wlan0
[Network]
DHCP=ipv4
Enable wpa_supplicant service at boot
# meta-mylayer/recipes-connectivity/wpa-supplicant/wpa-supplicant_%.bbappend (add to the above)
SYSTEMD_AUTO_ENABLE:${PN} = "enable"
With systemd-networkd and wpa_supplicant working together, the device connects to Wi-Fi automatically on boot.
Build and Flash
Run the build
bitbake core-image-base
The first build takes several hours depending on hardware. Apply build speed optimizations beforehand to reduce wait time.
Flash to SD card
cd tmp/deploy/images/raspberrypi5/
# Using bmaptool (recommended)
sudo bmaptool copy core-image-base-raspberrypi5.wic.bz2 /dev/sdX
# Using dd
bzcat core-image-base-raspberrypi5.wic.bz2 | sudo dd of=/dev/sdX bs=4M status=progress
sync
Verify
Insert the SD card into RPi5 and power on. Connect via serial console (UART) or HDMI.
# Check Wi-Fi
ip addr show wlan0
ping -c 3 8.8.8.8
If wlan0 has an IP address assigned, the setup is complete.
Known Issues and Workarounds
Wi-Fi interface not detected
Symptom: wlan0 doesn't appear in ip link output.
Cause: Missing brcmfmac-wcc kernel module.
Fix: Add to conf/local.conf:
MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS += "kernel-module-brcmfmac-wcc"
IMAGE_INSTALL:append = " wireless-regdb-static"
vc4graphics + meta-networking boot failure
Symptom: RPi5 fails to boot after adding the meta-networking layer.
Cause: Known conflict between the vc4graphics MACHINE_FEATURE and meta-networking (meta-raspberrypi issue #1383).
Fix: For headless builds where GPU acceleration isn't needed, remove vc4graphics.
# conf/local.conf
MACHINE_FEATURES:remove = "vc4graphics"
U-Boot USB issue
Symptom: U-Boot's USB Mass Storage (UMS) feature doesn't work on RPi5.
Cause: Device tree issue in U-Boot (meta-raspberrypi issue #1464).
Fix: This doesn't affect normal boot. If you need UMS functionality, monitor the issue for updates.
Wrapping Up
Building a headless Wi-Fi image for RPi5 with Yocto Scarthgap, step by step.
| Step | Key point |
|---|---|
| Layer setup | Don't forget meta-lts-mixins (scarthgap/u-boot) |
| MACHINE | raspberrypi5 |
| Wi-Fi | brcmfmac + brcmfmac-wcc + wireless-regdb-static |
| Networking | systemd-networkd + wpa_supplicant |
| Flashing | bmaptool or dd |
RPi5's RP1 southbridge introduced a different device tree structure from RPi4. But meta-raspberrypi and meta-lts-mixins handle the heavy lifting — the changes you need to make are limited.
Known issues (Wi-Fi driver, vc4graphics conflict) have documented workarounds. Check meta-raspberrypi issues periodically and remove workarounds as fixes land upstream.