Real Time kernel patching and cross compilation
This is a log of the recompilation of the latest available branch 4.1 for the raspberry pi, with the RT patch applied.
The target machine is a raspberry pi, with actual kernel : 4.1.13+ #826 PREEMPT.
I assume the ‘raspberrypi_target’ directory exists. (see an old post about kernel cross compilation..)
So , you have to update the kernel sources before doing the patching.
to avoid errors while fetching the new sources, from the raspberrypi_target/linux directory, you can split the fetching of the new files like this:
for m in `seq 1 100`;do git fetch –depth=$m;done
once done,switch to the latest stable branch 'rpi-4.1.y' (at the time i write this post) :
git checkout -b rpi-4.1.y
Now
its time to get the patch.
I assume you have a complete linux, branch 4.1.y … at the time i’m writing, the working patch for this version is located at :
https://www.kernel.org/pub/linux/kernel/projects/rt/4.1/patch-4.1.19-rt22.patch.gz
perform a save of your original,clean directory :
from the “raspberrypi_target” dir :
cp -a linux linux_before_patching
so, let’s get the patch:
wget https://www.kernel.org/pub/linux/kernel/projects/rt/4.1/patch-4.1.19-rt22.patch.gz
..And check for any error (do it!) before patching (option –dry-run performs a ‘blank’ patching with no file modifications ) :
from the linux dir where the patch .gz is :
zcat patch-4.1.19-rt22.patch.gz | patch -p1 –dry-run | grep FAIL
if the command returns nothing, everything is OK, now effectively apply the patch :
zcat patch-4.1.19-rt22.patch.gz | patch -p1
okay, now you have to get some base config for the configuration menu.
The simple way : use the raspberry pi connected to your network, and issue a : sudo modprobe configs
then download the config.gz file from the raspberry to your cross-compiler’s machine :
scp <username>@<ip.ip.ip.ip>:/proc/config.gz ./
now you should have the config.gz file into the /linux/ folder where you issued this command (on the compiling machine )
now deflate it :
zcat config.gz > .config
And be a little curious ! (ie : cat .config )
Okay, time to launch the menuconfig :
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- menuconfig
Now, the menu is on the screen. have to activate your options and customize, Then
“make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- -k -j5 ”
and voila(oups ..no ..), an error throws :
HOSTCC scripts/genksyms/lex.lex.o
arch/arm/kernel/asm-offsets.c:54:2: error: #error Your compiler is too buggy; it is known to miscompile kernels
#error Your compiler is too buggy; it is known to miscompile kernels
arch/arm/kernel/asm-offsets.c:55:2: error: #error and result in filesystem corruption and oopses.
#error and result in filesystem corruption and oopses.
^
make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 1
make[1]: Target `__build’ not remade because of errors.
make: *** [prepare0] Error 2
HOSTCC scripts/dtc/data.o
HOSTCC scripts/kallsyms
Damn…
Okay, lets get another cross compiler, form the github’s “raspberrypi/tools” dir :
cd to the home for your user name ( cd ~ )
then “git clone https://github.com/raspberrypi/tools.git“
… time to drink a cofee…
once done, the ‘tools’ folder is there.
okay, lets try rebuilding the menuconfig, this time using linaro gnueabi , from the tools.
the kernel modules will go to the ‘rtkern’ folder ..(create it : “mkdir rtkern” from your home folder )
make ARCH=arm CROSS_COMPILE=~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- INSTALL_MOD_PATH=~/rtkern
Once again,errors, on my machine : missing some “libstdc++.so.6″ libraries, fix it ( we need the 6th version)
Okay, got it.. i used the 32bit version but i’m on a 64bit machine with ubuntu , so :
first, lets add the path, arch and destination for modules to the system :
export ARCH=arm
export INSTALL_MOD_PATH=~/rtkern
export CROSS_COMPILE=~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-
notice i specified the -x64 version of the crosscompiler.
now, from the ‘linux’ directory, try again the menuconfig, it should work fine now :
make menuconfig
>> it’s time to activate the options we want, in the menu. for the RealTime aspects, you’ll have to activate ‘KERNEL PREEMPT FULL’ , and also the HIgh-Resolution timers .
then after customisation and save+exit , in the ‘linux’ folder, execute :
“make”
“make modules”
“make modules_install” <- the module are installed in the folder specified by the ‘INSTALL_MOD_PATH’ variable, obviously
now “cd ~/tools/mkimage”
check out your built image , it should be listed when doing :
“ls ~/raspberrypi_target/linux/arch/arm/boot -al”
notice there is Image and zImage that have been created.
first method :
-
type "./imagetool-uncompressed.py ../../raspberrypi_target/linux/arch/arm/boot/Image"
- the created boot image is in the current folder, named ‘kernel.img‘
- now you have to replace the files into the target pi , from ~/raspberrypi_target/linux/arch/arm/boot/kernel.img into the /boot/ folder
( NOTICE : the /boot/ folder depends on the image you installed on your SD card. beware in case of a ‘noobs’ image’ , because in this case , the right ‘/boot’ folder is not at the regular place ) - and rename/erase the target pi’s /lib/modules and /lib/firmware with the one freshly compiled,
- Use the mkknimg utility , located in the same folder. this one generates a kernel image from the zImage source, and the generated kernel.img file is configured to make use the of the device tree overlay (DTS) , then copy the created file to the /boot folder.
- Remove / rename the target pi’s /boot/overlays folder by the one contained into ~/raspberrypi_target/linux/arch/arm/boot/dts/overlays
Note : more infos about the DTS , DTB files, syntax and examples here :
https://www.raspberrypi.org/documentation/configuration/device-tree.md
and for the tool to convert from .DTS to .DTB (bin) :
sudo apt-get install device-tree-compiler
.. the source of mkknlimg tool here :
https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg
once done, do not forget to “sync” to ensure the data are written onto the SD.
then plug the fresh thing into the raspberry en enjoy.
uname -a gives a “Linux raspberrypi 4.1.20-rt22 #1 PREEMPT RT”