How to Build a PREEMPT_RT Real-Time Kernel for Raspberry Pi-Free Linux Device Drivers Course online

How to Build a PREEMPT_RT Real-Time Kernel for Raspberry Pi
Free Linux Kernel Development Course — Part 2 of 3: Building & Booting a Real-Time Kernel

← Previous Lecture  |  Next Lecture →

Build PREEMPT_RT Kernel Raspberry Pi Real-Time Linux Free Linux Device Drivers Course Free Embedded Systems Course CONFIG_PREEMPT_RT Cross-Compiling Linux Kernel
What You Will Learn
  • How to build a PREEMPT_RT kernel for Raspberry Pi using the current mainline-based workflow
  • Why you no longer need a separate real-time patch file on modern Raspberry Pi kernels
  • How to configure, cross-compile, and deploy the kernel to an SD card
  • How to verify that PREEMPT_RT is genuinely active after boot
  • Common build errors and how to resolve them

In the previous lecture of this free Linux kernel development course, you learned what PREEMPT_RT changes inside the kernel and why it matters. In this lecture, you will actually build one for a Raspberry Pi. The workflow here reflects the current, updated process for kernels based on Linux 6.12 and later, where PREEMPT_RT ships inside the Raspberry Pi kernel source tree as a ready-made configuration — a big simplification compared to the older approach of hunting for a version-matched patch file and hoping it applies cleanly.

Prerequisites

  • A Raspberry Pi 4 or Raspberry Pi 5 running a 64-bit Raspberry Pi OS install
  • A Linux PC or another Raspberry Pi for cross-compiling (native compiling on the Pi itself also works, just slower)
  • At least 20 GB of free disk space for kernel sources and build artifacts
  • A spare microSD card, or a working backup of your current one
  • Comfort with the previous lecture’s concepts: threaded IRQs, rt-mutexes, and soft real-time behavior

How the Modern Build Workflow Differs from the Old Patch-Based Method

Older real-time Linux tutorials walk you through downloading a patch-<kver>-rt<nn> file, matching it exactly to your kernel version, and applying it with the patch command — a process that regularly failed when the patch and kernel versions drifted apart even slightly. Since PREEMPT_RT merged into mainline Linux 6.12, the Raspberry Pi kernel source tree now ships dedicated real-time defconfig files, so the patch-download step is gone entirely for current kernels.

Old Workflow vs Current Workflow
Step Old Method (pre-6.12) Current Method (6.12+)
Get RT support Download a separate, version-matched RT patch Already included in kernel source; no patch file needed
Apply RT support Run patch -p1 and hope for no rejected hunks Select the RT defconfig or enable the config option directly
Configure Manually toggle Preemption Model to Real-Time Same menuconfig step, now natively part of the tree

Step 1: Install Build Dependencies

Update your system and install the packages needed to configure and cross-compile the kernel:

sudo apt update
sudo apt install -y git bc bison flex libssl-dev make libncurses-dev \
    crossbuild-essential-arm64

The crossbuild-essential-arm64 package provides the ARM64 cross-compiler toolchain, so you can build the kernel on a faster PC and deploy the result to the Pi.

Step 2: Fetch the Raspberry Pi Kernel Source

Clone the official Raspberry Pi Linux kernel tree, using a shallow clone to save time and space:

git clone --depth=1 --branch rpi-6.12.y https://github.com/raspberrypi/linux
cd linux
Note
Always check the Raspberry Pi GitHub repository for the latest supported “rpi-<version>.y” branch name before cloning, since branch names change as new kernel releases land.

Step 3: Select the Real-Time Defconfig

Set the cross-compilation environment variables, then choose the real-time-flavored default configuration that matches your board. Raspberry Pi 4 uses bcm2711, and Raspberry Pi 5 uses bcm2712:

export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

# For Raspberry Pi 4 / 400 / CM4:
make bcm2711_rt_defconfig

# For Raspberry Pi 5:
make bcm2712_rt_defconfig

If your kernel branch does not ship a dedicated _rt_defconfig yet, start from the standard defconfig and enable real-time support manually with make menuconfig, as shown next.

Step 4: Verify and Fine-Tune the Configuration

Open the interactive configuration menu to confirm the real-time option is active, and disable a few debug options that are known to inflate latency measurements:

make menuconfig
Menu Path Option Setting
General Setup > Preemption Model Fully Preemptible Kernel (Real-Time) Enabled (CONFIG_PREEMPT_RT=y)
Kernel hacking > Lock Debugging DEBUG_LOCKDEP, DEBUG_PREEMPT Disabled
Memory Debugging DEBUG_OBJECTS, SLUB_DEBUG Disabled
Why Disable These Debug Options?
Debug instrumentation adds extra checks and bookkeeping on hot code paths. Even when a debug feature never triggers a warning, its presence alone adds small, consistent overhead that shows up as extra jitter during latency testing.

If CONFIG_PREEMPT_RT is not visible in the Preemption Model menu, first enable CONFIG_EXPERT under General Setup — recent kernels hide the fully preemptible option behind it.

Step 5: Add a Custom Version Suffix (Optional but Recommended)

Tag your build with a recognizable suffix so uname -a clearly shows it later:

scripts/config --set-str LOCALVERSION "-v8-realtime"

Step 6: Build the Kernel, Modules, and Device Tree Blobs

make -j$(nproc) Image.gz modules dtbs

Replace $(nproc) with the number of CPU cores available on your build machine for the fastest possible build; this command produces the compressed kernel image, all loadable modules, and the device tree blobs needed to describe the hardware to the kernel at boot.

Step 7: Install Modules to the Target Root Filesystem

Mount your SD card’s root filesystem partition, then install the modules directly into it. Always set INSTALL_MOD_PATH to the mounted SD card path, never leave it unset when cross-compiling — otherwise you risk overwriting your build machine’s own kernel modules:

sudo env PATH=$PATH make ARCH=arm64 INSTALL_MOD_PATH=/media/$USER/rootfs modules_install

Step 8: Copy the Kernel Image, Device Tree Files, and Overlays

sudo cp arch/arm64/boot/Image.gz /media/$USER/bootfs/kernel8-rt.img
sudo cp arch/arm64/boot/dts/broadcom/*.dtb /media/$USER/bootfs/
sudo cp arch/arm64/boot/dts/overlays/*.dtb* /media/$USER/bootfs/overlays/

Copying the new kernel under a distinct filename such as kernel8-rt.img, instead of overwriting kernel8.img, keeps your original working kernel available as a fallback.

Step 9: Point the Bootloader at the Real-Time Kernel

Edit config.txt on the boot partition and add:

kernel=kernel8-rt.img
arm_64bit=1

Step 10: Boot and Verify PREEMPT_RT Is Active

Insert the SD card into the Raspberry Pi, power it on, and connect over SSH:

uname -a
cat /sys/kernel/realtime

A kernel with real-time support active will show PREEMPT_RT in the uname -a output, and /sys/kernel/realtime will read 1. If either check fails, revisit Step 4 and confirm CONFIG_PREEMPT_RT was actually enabled before the build.

Common Build Errors and Troubleshooting

Symptom Likely Cause Fix
Board fails to boot after flashing arm_64bit=1 missing in config.txt Add it explicitly when using a custom kernel filename
uname -a shows PREEMPT but not PREEMPT_RT CONFIG_PREEMPT_RT was not actually set before building Re-run menuconfig, confirm the setting, save, and rebuild
Modules fail to load after boot Modules installed to the wrong path or version mismatch Re-check INSTALL_MOD_PATH pointed at the correct mounted SD card partition
Host machine’s modules disappear Ran modules_install without INSTALL_MOD_PATH Always double-check this variable before running the install target

Best Practices for Building Real-Time Kernels

  • Always keep your previous working kernel image as a boot fallback
  • Use a distinct LOCALVERSION suffix so you can tell builds apart at a glance
  • Cross-compile on a PC for significantly faster build times than compiling natively on the Pi
  • Disable lock and memory debug options before running any latency benchmark
  • Track the exact commit or branch you built from, so results are reproducible later

Performance and Security Considerations

A real-time kernel trades a small amount of average-case throughput for tighter worst-case latency — expect slightly higher CPU overhead under heavy lock contention. From a security standpoint, treat a custom-built kernel the same as any other: keep it updated against upstream security fixes, and avoid exposing a real-time control system directly to untrusted networks, since a compromised high-priority process can starve the rest of the system through sched_rt_runtime_us if limits are not set appropriately.

Summary: Key Takeaways

  • Modern Raspberry Pi kernels (6.12+) ship real-time defconfigs, removing the old manual patch step
  • The build flow is: install toolchain, fetch source, select RT defconfig, configure, build, deploy, verify
  • Always confirm PREEMPT_RT is active via uname -a and /sys/kernel/realtime before trusting the build
  • Keep debug options disabled and a fallback kernel available at all times

Conclusion

You now have a working, verified PREEMPT_RT kernel running on Raspberry Pi hardware, built using the current mainline-based workflow rather than the older patch-file method. Having a real-time kernel installed is only half the story — the next lecture in this free Linux device drivers course and kernel series shows you how to objectively measure your system’s real-time behavior using the cyclictest tool, so you can prove your latency numbers instead of assuming them.

Frequently Asked Questions

1. Do I need to download a real-time patch file for a modern Raspberry Pi kernel?
No, not for kernels based on Linux 6.12 or later — the Raspberry Pi kernel tree includes ready-made real-time defconfigs.

2. Can I build the kernel directly on the Raspberry Pi instead of cross-compiling?
Yes, native compilation works, but it takes considerably longer than cross-compiling on a faster PC.

3. Which Raspberry Pi models are covered by this build process?
Raspberry Pi 4, Raspberry Pi 400, Compute Module 4, and Raspberry Pi 5 are all supported with their respective defconfig targets.

4. What does it mean if CONFIG_PREEMPT_RT isn’t visible in menuconfig?
It usually means CONFIG_EXPERT needs to be enabled first under General Setup, since the option is nested behind it on recent kernels.

5. Is it safe to overwrite my existing kernel.img file?
It is safer not to. Deploy the new kernel under a distinct filename and update config.txt, keeping your original kernel as a fallback.

6. How long does a full kernel build take?
It depends heavily on your build machine’s CPU core count; cross-compiling on a modern multi-core PC is typically much faster than native compilation on the Pi itself.

7. Does building a real-time kernel change my Raspberry Pi OS userspace?
No, only the kernel and its modules change. Your existing applications, packages, and filesystem remain untouched.

Continue the Free Linux Kernel Development Course

Next up: measure your real-time kernel’s actual latency using cyclictest.

Next Lecture: Latency Testing with cyclictest Browse All Free Courses

← Previous Lecture  |  Next Lecture →

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *