RPi-RT
Introduction
These are notes from cross-compiling a real-time (i.e. "fully preemptive") kernel for raspberry pi 3B+ and 4B. Adapted from https://www.instructables.com/64bit-RT-Kernel-Compilation-for-Raspberry-Pi-4B-/ and https://www.instructables.com/64bit-RT-Kernel-Compilation-for-Raspberry-Pi-4B-/
Prerequisites
Install the toolchain for cross-compilation:
sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev sudo apt install crossbuild-essential-arm64
Sources
Go to https://github.com/raspberrypi/linux/branches and select a branch. If you choose the default branch, you do not need to explicitly select it in the following command:
git clone --depth=1 --branch <branch> https://github.com/raspberrypi/linux
Find the matching real-time patch file in https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/ and download it. E.g.:
wget https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/6.1/patch-6.1.70-rt21.patch.gz
Apply the patch to the kernel sources:
cd linux gzip -cd ../patch-6.1.70-rt21.patch.gz | patch -p1 --verbose mkdir ../kernel-out
Configuring and building the kernel
Default configuration
rPi 3B+
make O=../kernel-out/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcmrpi3_defconfig
rPi 4B
make O=../kernel-out/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig
Turn on Real-Time support
make O=../kernel-out/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
Navigate to General->Preemption Model and select the Real-Time option.
Building the kernel
Compilation of the kernel will take several minutes, depending on PC power and number of parallel threads.
make -j16 O=../kernel-out/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs
The -j16 option is for the number of parallel processes and should probably be chosen no larger than the number of CPU cores.
Installation of the kernel on SD card
Take the SD card with your working Raspberry Pi OS or similar linux installation and insert it in an SD reader connected to the PC. If it mounts automatically, unmount as root to prepare for the following (not necessary, but makes the instructions easier). DO NOT unmount using the graphical EJECT button, as that will not just unmount but also disconnect the device.
Prepare SD card
Assuming the SD card is device /dev/sdd:
cd ../kernel-out mkdir -p mnt/{fat32,ext4} sudo mount /dev/sdd1 mnt/fat32 sudo mount /dev/sdd2 mnt/ext4
Copy files
cd ../linux sudo make O=../kernel-out/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=mnt/ext4 modules_install cd ../kernel-out sudo cp arch/arm64/boot/Image mnt/fat32/kernel8_rt.img # custom kernel name to preserve existing kernel sudo cp arch/arm64/boot/dts/broadcom/*.dtb mnt/fat32/ sudo cp arch/arm64/boot/dts/overlays/*.dtb* mnt/fat32/overlays/
Choose custom kernel for booting
sudo emacs mnt/fat32/config.txt
Add the line
kernel=kernel8_rt.img
to select your custom kernel.
Profit!
Insert the SD card in the pi, start it up and watch the boot messages. Hopefully you get to the login prompt. Once logged in, check the correct kernel was loaded with
uname -a