Cross-compile an RT kernel and deploy it to a headless Pi
Building natively on a Pi 4 takes hours. Cross-compiling on a normal workstation takes about forty minutes. And if you’ve never done it, the scary part isn’t the build — it’s that a bad kernel on a headless box means physically extracting the SD card. This page addresses both.
1. Toolchain
Section titled “1. Toolchain”sudo apt install crossbuild-essential-arm64 bc bison flex libssl-dev make \ libc6-dev libncurses5-dev2. Source, matched to your running kernel
Section titled “2. Source, matched to your running kernel”git clone --depth=1 --branch rpi-6.12.y \ https://github.com/raspberrypi/linux.gitcd linuxUse Raspberry Pi’s tree, not vanilla. RPi’s PREEMPT_RT is already merged in 6.12 and the board’s DT/overlays live there.
3. Configure
Section titled “3. Configure”export ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-make bcm2711_defconfig # Pi 4scripts/config --enable PREEMPT_RTscripts/config --set-str LOCALVERSION "-rt-cuckoo"make olddefconfigNow apply the patch — this is the whole reason you’re building a kernel rather than installing one.
4. Build
Section titled “4. Build”make -j$(nproc) Image modules dtbs5. Stage the artifacts
Section titled “5. Stage the artifacts”# Note the ABSOLUTE path. `~` does not expand inside a make variable —# INSTALL_MOD_PATH=~/out silently installs into a literal "~" directory# and you end up shipping an 80 KB tarball that contains nothing.make INSTALL_MOD_PATH=/home/you/out modules_installtar -C /home/you/out -czf rt-modules.tar.gz lib/modules/gzip -c arch/arm64/boot/Image > kernel-rt.img.gz6. Deploy without a rescue trip
Section titled “6. Deploy without a rescue trip”The rule: never overwrite the kernel that currently boots.
scp kernel-rt.img.gz rt-modules.tar.gz pi@host:/tmp/ssh pi@hostsudo tar -C / -xzf /tmp/rt-modules.tar.gzzcat /tmp/kernel-rt.img.gz | sudo tee /boot/firmware/kernel-rt.img > /dev/nullkernel8.img — the stock kernel — is untouched. Then add one line to
/boot/firmware/config.txt:
kernel=kernel-rt.imgsudo reboot7. Confirm
Section titled “7. Confirm”$ uname -aLinux gps-ntp 6.12.x-rt-cuckoo #1 SMP PREEMPT_RT ... aarch64