Manage cookies

We use cookies to improve our services. Read more about how we use cookies and how you can refuse them.

The necessary cookies help to make the website work properly.

Anonymous statistical cookies help to understand how visitors use the website.

  • Real Time Systems
    6 min | 44348

    #Raspberry Pi: Preempt-RT Patching Tutorial for Kernel 4.14.y

    Real Time Systems | 6 min | 44348

    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.

    Hardware & 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

    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 type head Makefile -n 4 inside the folder and you'll get something like this:

    # SPDX-License-Identifier: GPL-2.0
    VERSION = 4
    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 the softirq.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 
    # if if doesn't work use this:
    ~/rpi-kernel$ wget
    # Download a usb-dwc_otg fix
    ~/rpi-kernel$ wget

    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 a softirq.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

    Option 2:

    You can download the patched kernel sources from Github from:

    ##~/rpi-kernel$ git clone # update 18.03.2018: old repository##
    ~/rpi-kernel$ git clone # 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
    ~/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


    • Clone the repo outside the linux folder!
    • CROSS_COMPILE should point to arm-linux-gnueabihf- located under tools/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 and INSTALL_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 tested Tested: 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_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 set


    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)
    # For Raspberry Pi A(+), B(+), Zero (don't forget to change the kernel version, if you compile another version)

    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:

    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

    Performance tests between the Standard Raspian kernel and Preempt-RT Patched kernel are available here.

    Known Issue (updated 26.02.2018)


    Update 01.04.2018: These results are outdated, here you can find the new links:
    - Latency Performance
    - Kernel CPU & Network Performance

    I 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.

    RT Kernel IRQ Processes
    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


    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/ 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/ line 27: /root/rpi-kernel/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc: No such file or directory


    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


    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 :

    MODPOST vmlinux.o
    net/xfrm/xfrm_state.o: in the function « xfrm_state_alloc »:
    (.text+0x6bc): unknown reference to « tasklet_hrtimer_init » Makefile:1041 : target « vmlinux » failed make: *** [vmlinux] Error 1 (It might not be the exact words, because my PC is in French so I translated them)

    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:

    • Raspberry Pi 3 Model B
    • Raspbian Stretch Lite
    • Kernel branch rpi-4.14.y-rt (kernel=vmlinuz-4.14.43-rt31-rc1-v7+)
    • No changes in cmdline.txt Everything worked fine right away. None of the irq processes take more than 1.5%. Now going to install LinuxCNC...

    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, 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?