Raspberry Pi Kernel Real-time Build

Issue

If your Internet of Things (IoT) device built using a Raspberry Pi is inconsistent with GPIO communication, the cause maybe the kernel. The Raspberry Pi OS ships with a kernel tuned for “desktop” applications so that is responsive to user input. For example, this may result in missed GPIO reads and writes when moving the mouse.

Solution

Switching to a real-time kernel such as RTLinux helps insure your GPIO communication is more consistent.

Building the kernel takes a long time so use the fastest Pi you have. For this tutorial, the steps were performed on a Pi400 for a SD card that will be used in a Raspberry Pi Zero 2 W.

This tutorial distills the information in the following documents into a step-by-step guide. Read these sites to best understand what each step is and how to make adjustments for your setup.

0) Before we begin you may want to install “Raspberry Pi OS Lite” (no desktop) on a SD card using the Raspberry Pi Imager. Next update the OS to the latest version then reboot.


sudo apt update
sudo apt full-upgrade
sudo apt install raspberrypi-kernel-headers
sudo reboot

1) Install the required tools to configure and build the kernel.


sudo apt install git bc bison flex libssl-dev make libncurses5-dev

2) Create then change to the directory where the patch will be downloaded and built.


mkdir --parents ~/source && cd ~/source

3) Clone the kernel source for the Raspberry Pi.


git clone --depth=1 https://github.com/raspberrypi/linux

4) Get the RT kernel patch and apply it.

  1. Run the command uname -r to see which version of the Linux kernel you currently have installed.
  2. Search the RT kernel patch site to find the kernel patch version matching your kernel version.
  3. For this tutorial, uname returned “6.6.31+rpt-rpi-v8” therefore the wget URL is https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/6.6/older/patch-6.6.31-rt31.patch.gz
  4. Unzip the patch.
  5. Patch the linux kernel with the RT patch. Again, you will need to edit the command to specify the correct version.

wget https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/6.6/older/patch-6.6.31-rt31.patch.gz
gunzip patch-6.6.31-rt31.patch.gz
cd linux
patch -p1 -i ../patch-6.6.31-rt31.patch

5) Set the config variables based on this table and the version of your current kernel. This tutorial is building a 64-bit kernel.

64-bit kernelRaspberry Pi 3, 3+, 4, 400 and Zero 2 W, and Raspberry Pi Compute Modules 3, 4 and 4S KERNEL=kernel8
make bcm2711_defconfig
Raspberry Pi 5 KERNEL=kernel8
make bcm2711_defconfig

KERNEL=kernel8
make bcm2711_defconfig
CONFIG_LOCALVERSION="-6.6.31-rt31-patched"

6) Using menuconfig, follow these steps to configure the kernel for real-time.

  1. Uncheck “Virtualization” in the main menu
  2. Select “General setup —>”
  3. Select “Preemption Model (Preemptible Kernel (Low-Latency Desktop)) —>”
  4. Check “Fully Preemptible Kernel (Real-Time)”. This is listed if step 5 is completed.
  5. Select “Timers subsystem –>”
  6. Uncheck “Old Idle dynticks config” (Skip this for pi3 models.) SEE: Linux PREEMPT-RT kernel tuning example for EPICS IOC
  7. Check “High Resolution Timer Support”
  8. Select “<Exit>” to return to menu “General setup”
  9. Select “<Exit>” to return to go up to top level
  10. Select “Kernel features —>”
  11. Select “Timer Frequency (250HZ) —>”
  12. Check “1000Hz”
  13. Select “<Exit>” to return to go up to top level
  14. Select “<Exit>” to exit and save
  15. Choose Yes to save your new configuration

make menuconfig

7) (Only for pi3) Set the kernel version in config.txt depending on the rt patch you’ve installed.

  1. Edit /boot/config.txt
  2. Look for section [pi3+]
  3. kernel=vmlinuz-6.6.31-rt31


sudo nano /boot/config.txt

8) Build and install the kernel.


make -j6 Image.gz modules dtbs
sudo make -j6 modules_install
sudo cp /boot/firmware/$KERNEL.img /boot/firmware/$KERNEL-backup.img
sudo cp arch/arm64/boot/Image.gz /boot/firmware/$KERNEL.img
sudo cp arch/arm64/boot/dts/broadcom/*.dtb /boot/firmware/
sudo cp arch/arm64/boot/dts/overlays/*.dtb* /boot/firmware/overlays/
sudo cp arch/arm64/boot/dts/overlays/README /boot/firmware/overlays/

9) If no errors have occurred, the final step is to reboot the computer. After the reboot, verify the new kernel by running uname -srvo. For this tutorial uname returned "Linux 6.6.34-rt31-v8+ #1 SMP PREEMPT_RT Mon Jun 24 00:54:08 CDT 2024 GNU/Linux". Notice "PREEMPT_RT" in the name, RT is for real time.


uname -srvo

Conclusion

Linux has different kernels tuned for specific purposes such as general desktop computing and IoT devices. The Raspberry Pi OS ships with a kernel tuned for desktop applications. For IoT development, the real-time kernel will provide a more consistent communication with sensors and PWM controlled devices.

Thank you to René Vogel for determining the settings needed for the pi3+.