Real-time kernel (PREEMPT_RT)#
Why#
A standard Linux kernel isn’t designed to guarantee a maximum reaction delay: a critical kernel section can delay interrupt handling by several milliseconds under load. Invisible for most use cases; unacceptable for capturing a PPS signal at nanosecond precision. The PREEMPT_RT patch makes the kernel’s own critical sections preemptible, bringing worst-case interrupt latency down from several milliseconds to a few tens of microseconds.
How#
Installation#
apt update
apt install -y linux-image-rpi-v8-rt linux-headers-rpi-v8-rt
apt list --installed 2>/dev/null | grep rpi-v8-rt
ls -lh /boot/firmware/kernel8_rt.imgOn Raspberry Pi 5, the model-specific package
linux-image-rpi-2712-rtdoes not exist in the official repositories at the time of writing. The generic packagelinux-image-rpi-v8-rt(generic ARMv8, 4 KiB pages) is the officially reproducible path, without Pi 5-specific Cortex-A76 optimizations, but fully functional.
Selecting it at boot#
The Pi 5 firmware loads the standard kernel by default, not the freshly
installed RT kernel: it needs to be explicitly redirected in
/boot/firmware/config.txt:
[pi5]
kernel=kernel8_rt.imgPitfalls to avoid#
A typo in the filename is silently ignored. The package produces
kernel8_rt.img(underscore), notkernel8-rt.img(hyphen). An invalidkernel=directive produces no boot error, the firmware simply falls back to the default kernel, creating the illusion of running RT when that is not the case. Same trap asconfig.txtin general (see the Firmware chapter): always verify the result, never assume no error means success.
- Relying on
/sys/kernel/realtimeto confirm the install. This sysfs attribute is specific to an out-of-mainline patch (used by LinuxCNC), and is absent on a perfectly functional RPi v8-rt kernel. It’s not a reliable test, see the Verify section below for the correct method. - Expecting
nohz_full/rcu_nocbsfrom the next chapter to work. Thelinux-image-rpi-v8-rtkernel is not built withCONFIG_NO_HZ_FULL. Thenohz_full=andrcu_nocbs=boot parameters are accepted without error but have no real effect, onlyisolcpus=works on this kernel (details in the Firmware chapter).
Verify#
reboot
# … reconnect …
uname -a
# Should contain: …-v8-rt … #1 SMP PREEMPT_RT … aarch64
# BEFORE fix: 6.12.75+rpt-rpi-2712 #1 SMP PREEMPT (standard kernel)
# AFTER fix: 6.12.75+rpt-rpi-v8-rt #1 SMP PREEMPT_RT (RT kernel)
dmesg | grep -E '\bPREEMPT_RT\b'
# Should show the boot banner line with PREEMPT_RT
dmesg | grep -i "Preemptible hierarchical RCU"
# Should return: "rcu: Preemptible hierarchical RCU implementation."If uname -r still shows the -rpi-2712 suffix instead of -v8-rt,
three causes in order of observed frequency: a typo in the filename, a
misplaced [pi5] section in config.txt (must precede [all]), or the
kernel8_rt.img file simply missing. vcgencmd get_config kernel
confirms which file the firmware actually loaded.
📚 Going further
The PREEMPT_RT patch, maintained by Thomas Gleixner and the community since 2004, was merged into the mainline Linux kernel in version 6.12 (November 2024), this project benefits from that directly. It acts on three levels: converting kernel spinlocks into preemptible
rt_mutexwith priority inheritance, converting softirqs into schedulable threads, and threaded interrupt handlers (each IRQ becomes an individually schedulable thread with its own priority, which is what lets the next chapter give the PPS IRQ aSCHED_FIFO 99priority, the highest possible).