Real-Time Kernel on Ubuntu Core

Buğra Aydoğar
4 min readAug 25, 2021

Ubuntu Core is a well-managed and ultra-secure embedded operating system. It basically means that Canonical fixes around ~1000 CVE every year and Ubuntu Core devices benefit from these fixes.

From time to time, developers might want to build their own custom kernel to develop a new driver, to evaluate different real-time patches and so on. This article will explain how to patch Ubuntu Kernel with PREEMPT_RT and create a kernel snap. Finally, the Ubuntu Core image will be created using the custom RT patched kernel.

In addition to that many times, you don't really need a PREEMPT_RT patch. My colleague Diego Bruno has written a great post describing how to build a low-latency kernel for Raspberry Pi. Feel free to have a look at his post if a low-latency kernel is something that you are looking for.

Prerequisites

  • It is assumed that you have an idea about the Ubuntu Core and snaps.
  • It is assumed that you already know how to build a Linux kernel.
  • It is assumed that you are using Ubuntu 18.04 or later ( preferably 20.04 )
  • It is assumed that you already installed LXD in your system. If not, you can find the details here.

Choosing the Kernel and RT Patch Versions

Ubuntu forks the mainline kernel, applies lots of security and performance patches and renames it and according to their own labelling. Therefore, it is crucial to understand the Ubuntu Kernel version and the corresponding mainline kernel version. Here is the web page that enlightens the mystery.

I have selected Ubuntu-5.4.0–65.73 as reference since it is the latest version and there is a RT patch available for it here. To clarify it, Ubuntu-5.4.0–65.73 is based on Linux Kernel 5.4.78 so, you have to choose corresponding RT patch which is 5.4.78-rt44.

Creating and Building the Kernel Snap

Creating the Kernel snap is quite easy by using the kernel plugin. It helps you to build the kernel without manually running or implementing all the steps in your snapcraft.yaml file.

As it can be seen in the following snapcraft.yaml file, the generic defconfig is used and on top of that, preempt is enabled and aufs is disabled due to the build errors after applying the RT patch. If you need aufs, then feel free to dive deep and fix the issue. In this context, we don't need it so it is disabled.

I prefer to build in a Ubuntu 20.04 container using LXD and would definitely suggest doing so.

Let’s start by creating a new container and dive into it.

lxc launch ubuntu:20.04 focal
lxc shell focal
snap install snapcraft --classic

Now, it is time to build your custom kernel.

git clone https://github.com/bugraaydogar/ubuntucore-realtime-kernel cd ubuntucore-realtime-kernel
snapcraft --destructive-mode

If everything goes well, you will be able to see your new RT patched custom kernel. To pull it from the container to your desktop, you could use the following command.

lxc file pull focal/root/your snap path

Great you build your own custom kernel snap.

Creating the Ubuntu Core 18 Image

There is a great tutorial about how to create Ubuntu Core 18 image. I would definitely suggest reading it here since I won’t describe the basic steps here. Once you have created your model.json and sign it, it is time to build the image with the ubuntu-image utility.

Here is the trick, it is possible to replace snaps that are delivered by Canonical by using the “extra-snaps” parameters. Here it is;

ubuntu-image snap --extra-snaps my-custom-kernel.snap my-model.model

Then, everything should be nice and smooth.

If you would like to create Ubuntu Core 20 image, the instructions would be quite different since there is no kernel plugin available just yet.

Booting on Qemu

If you came so far, you deserved congrats! Finally, you will be able to start testing your brand new kernel. As you already created your image, you could basically, start the Qemu with the following command.

qemu-system-x86_64 -enable-kvm -smp 2 -m 1500 -netdev user,id=mynet0,hostfwd=tcp::8022-:22,hostfwd=tcp::8090-:80 -device virtio-net-pci,netdev=mynet0 -drive file=pc.img,format=raw

Summary

As can be seen in the steps above, the biggest challenge is choosing the right Ubuntu Kernel and the RT patch. The rest of the work is quite straightforward. In addition to that, please keep in mind that, PREEMPT_RT might not be always the thing you are looking for. There is also a low-latency kernel snap that is maintained by Canonical and can be found on this link. Please keep in mind that it is currently in beta phase and available for testing and evaluating purposes.

References

[1] https://people.canonical.com/~kernel/info/kernel-version-map.html

[2] https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.4/

[3]https://snapcraft.io/docs/kernel-plugin

[4]https://snapcraft.io/tutorials/create-your-own-core-18-image#1-overview

[5] https://forum.snapcraft.io/t/snapping-a-lowlatency-kernel-for-your-raspberry-pi/20462

--

--