In this blog post, you will learn how to compile a PREEMPT_RT kernel for the Up Squared (Up2) board.
The Up2 is an x86 Intel Apollo Lake-based mini-computer. Features such a quad-core CPU, dual Ethernet, a PCI-Express mini port and a Raspberry Pi compatible pin header make this board very attractive for high-end RT-Linux applications.
I was looking for a reasonably priced computer which can run ROS and Machinekit decently and still has leftover resources to render a fancy Qt/QML GUI and is relatively future-proof in terms of image recognition and machine learning.
Besides being an interesting x86 platform, there a new AI vision kit being sold as an extension for the Up2, which can become handing when implementing object and image recognition with ROS.
Someone from the community also proved that it is possible to run an external GPU via the Mini PCI-Express port.
All in all, Up2 seems like an excellent platform for robotics applications with ROS.
The Up2 comes with a Linux distribution called Ubilinux. Ubilinux is a Debian based distribution supported by Emutex. It comes with everything pre-installed to use the Raspberry Pi compatible pin headers of the Up2, this includes a kernel driver.
I decided against using the Ubilinux distribution since the modifications made by Emutex aren't transparent and I prefer to be in control of what my Linux distribution has installed or not.
The installation of a vanilla Debian Stretch works fine on the Up2. The only shortcoming I noticed, was that the GPIO access requires the Up2 kernel driver.
Therefore I decided to compile the Up2 kernel with the PREEMPT_RT patch myself.
Up2 PREEMPT_RT Kernel
Now we come to the quintessence of this article, compiling and installing the PREEMPT_RT kernel for the Up2.
I started with the Up Board kernel build guide and adapted it for Debian Stretch and the PREEMPT_RT patch and modifications to the kernel configuration.
First of all, install the build dependencies.
sudo apt-get update sudo apt-get install -y git build-essential kernel-package libncurses5-dev libssl-dev
Then continue by cloning the Ubilinux Kernel repository.
cd mkdir repos cd repos git clone --depth=1 https://github.com/emutex/ubilinux-kernel.git -b upboard-4.9 linux-upboard
Next, download and apply the PREEMPT_RT kernel patches. To find out the kernel version of your kernel source tree run
make kernelversion. In my case it was
Based on this version number, you need to look for a matching PREEMPT_RT patch in the kernel archives.
cd linux-upboard wget https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/4.9/older/patch-4.9.47-rt37.patch.xz unxz -cd patch-4.9.47-rt37.patch.xz | patch -p1
Then you can create the default kernel configuration:
The kernel now needs to be configured to use the RT scheduler. Either use the kernel menuconfig wizard using
make menuconfig or use your preferred text editor to edit the
.config file directly.
You need to set following kernel configuration parameters:
HIGH_RES_TIMERS=y CONFIG_PREEMPT_RT_FULL=y CONFIG_HZ_1000=y CONFIG_HZ=1000 CONFIG_OF=n
I encourage you also to disable the CPU idle state and to set the default CPU frequency governor to performance.
CONFIG_CPU_IDLE=n CONFIG_INTEL_IDLE=n CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
Next, you need to compile the Linux kernel.
make -j`nproc` && make -j`nproc` bindeb-pkg
Before the compilation starts, you might be asked to set additional configuration parameters. It should be safe to use the defaults, but note that debugging features might be enabled which could cause additional latencies.
After the compilition is complete (which can take several hours), you will find a few debian packages in the parent directory of the
$ ls linux-4.9.45-rt57-upboard-rt+_4.9.45-rt57-upboard-rt+-3_amd64.changes linux-firmware-image-4.9.45-rt57-upboard-rt+_4.9.45-rt57-upboard-rt+-3_amd64.deb linux-headers-4.9.45-rt57-upboard-rt+_4.9.45-rt57-upboard-rt+-3_amd64.deb linux-image-4.9.45-rt57-upboard-rt+_4.9.45-rt57-upboard-rt+-3_amd64.deb linux-libc-dev_4.9.45-rt57-upboard-rt+-3_amd64.deb linux-upboard
Install the new kernel package with:
sudo dpkg -i linux-*.deb
Restart your system and you should be running a PREEMPT_RT kernel.
$ uname -a Linux upsquared 4.9.45-rt57-upboard-rt+ #3 SMP PREEMPT RT Fri Sep 14 19:27:04 CEST 2018 x86_64 GNU/Linux
Tuning RT parameters
Unfortunately installing an RT kernel is not enough. For many applications, you still need to tweak the kernel parameters and other properties in order to get the required RT performance.
I won't cover how to do that in this post. However, I can encourage you to take a look at the "Improving the Real-Time Properties" guide.
A quick hint at this point. To modify the kernel boot arguments use the following:
/etc/default/grub and append your kernel options to the
GRUB_CMDLINE_LINUX_DEFAULT line an then automatically re-generate the grub.cfg file with:
grub-mkconfig -o /boot/grub/grub.cfg
Don't try to modify the grub config by hand.
In this article, you learned how to compile a PREEMPT_RT kernel for the Up Squared board. The guide also may be helpful for other compiling kernels for other boards as well.
If you have enjoyed reading this article, please subsribe to stay up to date with my newest blog posts.