- Table of contentShow
You can still read this article, but a new tutorial is available here: There are a lot of tutorials for Raspberry Pi kernel patching using Preempt-RT, but I needed about 15 hours to get it working! I hate Kernel patching! and I have to say, that's not my first time. I have a system working with Ubuntu, RTAI and an Ethercat master. I patched the system more than once. But it is/was always a new thing! and It costs a lot of time! ;)
Then, you have another tutorial here. I only hope that the repo gets official. It could reduce the time to get the RT kernel working, if it is kept updated.
1. Update: 18.03.2018: The repository is now here. It is a branch from the official Raspberry Pi kernel repository.
2. Update 01.04.2018: Before patching the kernel with Preempt-RT, I recommend that you check the following performance tests:
- Latency Performance
- Kernel CPU & Network PerformanceHardware & Software
Kernel Patch
Preempt-RT is a popular patch for the Linux kernel to transform Linux into a real-time operating system. I patched the standard Raspian kernel with the Preempt-RT Patch and cross-compiled it on my host computer, which is running Ubuntu 16.04 LTS.
Getting the Raspberry Pi Kernel Sources & Patching the Kernel with Preempt-RT
Note: I usually don't include the path (e.g.
~/rpi-kernels$
) where I type the commands. This time I did it because It makes the reading easier.Option 1: From Zero to Success! ;)
(Check Option 2, it is easier,
but not official!Update 18.03.2018: It is official! Use that option!)To start the cross-compilation you need to download the latest kernel sources from Github.
~/rpi-kernels$ git clone https://github.com/raspberrypi/linux.git
I switched to the kernel version 4.14.21 using
~/rpi-kernels$ cd linux ~/rpi-kernels/linux$ git checkout d9db059cb982c5478a464c1ff8ce8b17f7768dcc # --> (4.14.21)
The next step is to patch the kernel with the Preempt-RT patch. Be careful, the patch need to match the kernel version. To look for the right patch, open the
Makefile
located on the kernel sources folder or typehead Makefile -n 4
inside the folder and you'll get something like this:# SPDX-License-Identifier: GPL-2.0 VERSION = 4 PATCHLEVEL = 14 SUBLEVEL = 21
At the time of writing this post, the latest kernel version was 4.14.21. But the latest Preempt-RT patch is for version 4.14.20. You can switch the Linux sources to this version using
git checkout 7e83b2ff485cacbf73d27f821e07a8c78ad8cc68
, but I tried with the 4.14.21 (d9db059cb982c5478a464c1ff8ce8b17f7768dcc
) and It worked (with some changes on thesoftirq.c
file), but It usually doesn't work. ;)Patches for older kernels can be found in the folder called
older
, or surfing here.Download the Preempt-RT patch corresponding to the VERSION, PATCHLEVEL & SUBLEVEL that you have and the usb-dwc_otg-fix patch using:
# Download the Preempt-RT Patch ~/rpi-kernel$ wget https://www.kernel.org/pub/linux/kernel/projects/rt/4.14/patch-4.14.20-rt17.patch.gz # if if doesn't work use this: ~/rpi-kernel$ wget https://www.kernel.org/pub/linux/kernel/projects/rt/4.14/older/patch-4.14.20-rt17.patch.gz # Download a usb-dwc_otg fix ~/rpi-kernel$ wget https://raw.githubusercontent.com/fedberry/kernel/master/usb-dwc_otg-fix-system-lockup-when-interrupts-are-threaded.patch
The usb-dwc_otg patch fix a system lockup when interrupts are threaded, especially the corresponding to the USB.
Note: If the links are not working, copies of these patches are included here.
Patch then the kernel using:
~/rpi-kernel/linux$ zcat ../patch-4.14.20-rt17.patch.gz | patch -p1 # --dry-run: just to see what is going to be patch ~/rpi-kernel/linux$ patch -i ../usb-dwc_otg-fix-system-lockup-when-interrupts-are-threaded.patch -p1 --dry-run # continue when all hunks are here and no error is shown ~/rpi-kernel/linux$ patch -i ../usb-dwc_otg-fix-system-lockup-when-interrupts-are-threaded.patch -p1
Check if you have errors on every step. In my case, I got two errors while patching the
softirq.c
file. I got asoftirq.c.rej
file in the same folder and I needed to finish the patch using my hands. I included this file, and you can replace the file using:~/rpi-kernel/linux$ cd kernel ~/rpi-kernel/linux/kernel$ wget https://raw.githubusercontent.com/lemariva/RT-Tools-RPi/master/patched_files/softirq.c
Option 2:
You can download the patched kernel sources from Github from:
##~/rpi-kernel$ git clone https://github.com/TiejunChina/linux.git # update 18.03.2018: old repository## ~/rpi-kernel$ git clone https://github.com/raspberrypi/linux.git # update 18.03.2018: new repository ~/rpi-kernel$ cd linux ~/rpi-kernel/linux$ git checkout rpi-4.14.y-rt # I tested the version rpi-4.14.21 and it worked.
It includes the
usb-dwc_otg-fix
(and some other patches?).Configuring the Tool Chain for Compilation
For cross-compiling the kernel, as I said before I used my host computer running Ubuntu 16.04 LTS. I used the tool chain for ARM downloaded and configured as:
~/rpi-kernel$ git clone https://github.com/raspberrypi/tools.git ~/rpi-kernel$ export ARCH=arm ~/rpi-kernel$ export CROSS_COMPILE=~/rpi-kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- ~/rpi-kernel$ export INSTALL_MOD_PATH=~/rpi-kernel/rt-kernel ~/rpi-kernel$ export INSTALL_DTBS_PATH=~/rpi-kernel/rt-kernel
Notes:
- Clone the repo outside the
linux
folder! CROSS_COMPILE
should point toarm-linux-gnueabihf-
located undertools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/
, you are definitely using another system path, then you should change this.- The directories specified by
INSTALL_MOD_PATH
andINSTALL_DTBS_PATH
define where the modules go after the installation.
Configuring the Kernel
For Raspberry Pi 2/3 Model B, execute these commands inside the
linux
folder:~/rpi-kernel/linux$ export KERNEL=kernel7 ~/rpi-kernel/linux$ make bcm2709_defconfig
Only as info, for Raspberry Pi Model A(+), B(+), Zero the following commands are needed
(not testedTested: check here.):~/rpi-kernel/linux$ export KERNEL=kernel ~/rpi-kernel/linux$ make bcmrpi_defconfig
You need to enable and change in the kernel configuration two/three settings:
CONFIG_PREEMPT_RT_FULL
HIGH_RES_TIMERS
CONFIG_HZ
: this could improve USB throughput on the RPi (unconfirmed)!
Option 1
You can edit the
.config
file using~/rpi-kernel/linux$ nano .config
and search for the options using
CTRL+W
and setHIGH_RES_TIMERS=y CONFIG_PREEMPT_RT_FULL=y CONFIG_HZ_1000=y CONFIG_HZ=1000
Do not insert spaces!
Option 2
You can start the
menuconfig
typing:~/rpi-kernel/linux$ make menuconfig
and look for the options
CONFIG_PREEMPT_RT_FULL
: Kernel Features → Preemption Model (Fully Preemptible Kernel (RT)) → Fully Preemptible Kernel (RT)- Set
CONFIG_HZ
to 1000Hz: Kernel Features → Timer frequency = 1000 Hz - Enable
HIGH_RES_TIMERS
: General setup → Timers subsystem → High Resolution Timer Support
After changing these options, don't forget to save the
.config
file (option Save) and then exit.Build the Kernel & Transfer to the Raspberry Pi
~/rpi-kernel/linux$ make -j4 zImage ~/rpi-kernel/linux$ make -j4 modules ~/rpi-kernel/linux$ make -j4 dtbs ~/rpi-kernel/linux$ make -j4 modules_install ~/rpi-kernel/linux$ make -j4 dtbs_install
Choose the right
-jX
parameter according to the number of processors that your host computer has. In my case 4.Take a coffee or may be 2! ;).
After the compilation is completed, then compress all files to tranfer them to the Raspberry Pi.
~/rpi-kernel/linux$ mkdir $INSTALL_MOD_PATH/boot ~/rpi-kernel/linux$ ./scripts/mkknlimg ./arch/arm/boot/zImage $INSTALL_MOD_PATH/boot/$KERNEL.img ~/rpi-kernel/linux$ cd $INSTALL_MOD_PATH ~/rpi-kernel/rt-kernel$ tar czf ../rt-kernel.tgz *
Then, transfer the resulting '.tgz' file to the Raspberry Pi using
scp
and your ssh credentials:~/rpi-kernel$ scp rt-kernel.tgz pi@<IPAddress>:/tmp
Change
<IPAddress>
to the corresponding IP of your Raspberry Pi.Installing the Kernel Image, Modules & Device Tree Overlays
Before you start doing this, be sure that you've already saved the important data from your Raspberry Pi (may be you should do a MicroSD card backup). The following commands replace the kernel, modules & device tree overlays without making any backup. That means, if it doesn't work because errors ocour, then you are not going to be able to boot your Raspberry Pi as usual. You can get your files from the MicroSD (e.g. connecting to your host computer), but it is not going to boot. Be also aware there could be compatibility issues with some drivers. This tutorial helps you to install the kernel version
4.14.21
. Discussion for kernel compatibilities are here.If you are sure to continue, type the following:
~$ cd /tmp /tmp$ tar xzf rt-kernel.tgz /tmp$ cd boot /tmp/boot$ sudo cp -rd * /boot/ /tmp/boot$ cd ../lib /tmp/lib$ sudo cp -dr * /lib/
Add the following entry to
/boot/config.txt
:~$ sudo nano /boot/config.txt # Add the following option: ## For Raspberry Pi v3 Model B (don't forget to change the kernel version, if you compile another version) kernel=vmlinuz-4.14.21-rt17-v7+ # For Raspberry Pi A(+), B(+), Zero (don't forget to change the kernel version, if you compile another version) kernel=vmlinuz-4.14.21-rt17+
Change the version number corresponding to the kernel version that you've compiled.
Add the following entries to
/boot/cmdline.txt
, otherwise it is going to hang everytime you want to download something etc. (the patch should resolve this, but It didn't work!):~$ sudo nano /boot/cmdline.txt # Add the following options: dwc_otg.fiq_enable=0 dwc_otg.fiq_fsm_enable=0 dwc_otg.nak_holdoff=0
You can also disable the Low Latency Mode (llm) for the MicroSD card:
~$ sudo nano /boot/cmdline.txt # Add the following option: sdhci_bcm2708.enable_llm=0
After all the changes, reboot your Raspberry Pi:
~$ sudo reboot
If all the stars are aligned, you get the Preempt-RT kernel working! I am just kidding, I should work without problems! ;P. You can test if the kernel is working, typing:
~$ uname -r 4.14.21-rt17-v7
Performance tests between the Standard Raspian kernel and Preempt-RT Patched kernel are available here.
Known Issue (updated 26.02.2018)
Performance!
Update 01.04.2018: These results are outdated, here you can find the new links:
- Latency Performance
- Kernel CPU & Network PerformanceI found a problem on the patched kernel, and I thing the problem is in every Preempt-RT Raspbian versions. The IRQ/39-dwc_otg process uses more than 30% of the CPU! That's too much! The interruption is related with the USB irq: A known problem of the Preempt-RT patches. I read that the option
dwg_otg.speed=1
in/boot/cmdline.txt
should mitigate the problem, but It didn't work.Fig. 3: 3 IRQ/39-dwc_otg processes use more that 30% of the CPU! If you have another solution to this problem, write a comment!
Download Files
Here you can download the compiled files for Option 1 and Option 2.
Other References
- Clone the repo outside the
We use cookies to improve our services. Read more about how we use cookies and how you can refuse them.
Pj 03.02.2018
Hey ! Thanks for this clear tutorial ! I've installed PREEMPT_RT on my Pi Zero with another website but my card freezes when i'm trying to ssh, or while sshing, when i execute some custom programs (that I am very sure of). Does it happen for you too ?
Ozcan 06.11.2018
your hard work is the best and up-to-date that I have found! Thank you very much! I have a cross compiler error when I make "~/rpi-kernel/linux$ make -j4 zImage"
root@ubuntu:/home/ozcan/rpi-kernel/linux# make -j4 zImage ./scripts/gcc-version.sh: line 26: /root/rpi-kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc: No such file or directory ./scripts/gcc-version.sh: line 27: /root/rpi-kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc: No such file or directory
[edited]
make[1]: [kernel/bounds.s] Error 127 make[1]: Waiting for unfinished jobs.... UPD include/generated/timeconst.h Makefile:1085: recipe for target 'prepare0' failed make: *** [prepare0] Error 2
Ozcan 06.11.2018
My cross-platform is Ubuntu x64 18.04 LTS on vmware
Paulo 06.13.2018
FYI, I just followed your tutorial, worked with the latest lite raspbian (2018-04-18 release). The patched kernel is: 4.14.43-rt31-rc1-v7+
Compiled on Ubuntu 16.04 for RPi 3 B
JM 06.19.2018
Hi,
Thanks for your great tutorial, I'm trying to install the preempt_rt patch myself but I get an error while building the kernel. After the make -j4 zImage command, everything is working fine for 10 minutes, then I have the following :
Current set up: UBUNTU 16.04. Preempt_rt patch 4.16.15. Linux 4.16.15. Cross-compiled with the x64 version provided in raspberry/tools If you have any idea why this is happening, I would appreciate. Thanks!
Dante 07.01.2018
Thanks for the guide! My personal experience:
Pedro 07.07.2018
Hi, First of all thanks for this great tutorial. I've been trying to install the patch on pi1 model but I get the message: " Timed out waiting for device dev-disk-by........ Dependency failed for /boot Dependency failed for local File System Timed out waiting for device dev-ttyAMA0.device you are in emergency mode " I've got Raspbian 2018-06-27-raspbian-stretch-lite.zip, raspberry pi 1 model b and the cmdline.txt and config.txt as you have advised. I've tried multiple times on differents SD Cards but I've got the same. Hope you can help me.
Himel Patel 07.18.2018
Hi, Thanks for the great tutorial! I got a bit stuck at the end, when I booted up my pi model B after all the changes I got:
raspberrypi-firmware soc:firmware: Get Throttled mailbox call failed bcm2835_thermal soc:thermal: invalid response bcm2835_thermal soc:thermal: Could not get registers: -22
I source used the source code from the rpi-4.14.y-rt branch on github
Sil 11.14.2018
Hi, I need to install PREEMPT_RT on my RPI 3 and I don't have access to a CPU with Linux for the cross compilation, could you help me? thank you
gowsalya 02.25.2019
Great post! I am actually getting ready to across this information, It’s very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.
SWASTIK MITTAL 09.30.2019
Thanks, for this post. It is very well written and informative. I was able to cross compile the preempt-rt using my ubuntu 16.04 (64 bit). I used the rt branch (4.14) giving me rt(4.14.91-rt49-v7+). I had to make a minor change in "export CROSS_COMPILE" setting "gcc-linaro-arm-linux-gnueabihf-raspbian-x64" instead of "gcc-linaro-arm-linux-gnueabihf-raspbian" which fix build issues for me.
But when I make changes in the raspberry pi (pi 3 model B) as mentioned in the post and reboot it, my raspberry pi boots (also displays message about threaded IRQ's) but then freezes immediately after. I did add "dwc_otg.fiq_fsm_enable=0 dwc_otg.fiq_enable=0 dwc_otg.nak_holdoff=0" to handle fast interrupts. Can you help me with this?