/linux-real-time-kernel-builder

build and setup RT kernel for the ROS 2 testing

Primary LanguageDockerfileApache License 2.0Apache-2.0

Build RT_PREEMPT kernel for Raspberry Pi

RPI RT Kernel build

Introduction

This README describes necessary steps to build and install RT_PREEMPT Linux kernel for the Raspberry Pi board. RT Kernel is a part of the ROS2 real-time system setup. Raspberry Pi is a reference board used by the ROS 2 real-time community for the development. RT Kernel is configured as described in Kernel configuration section. Kernel is built automatically by the Github action, and the artifacts are located under the build stable. Please follow installation instructions to deploy a new kernel to the RPI board.

Raspberry Pi RT Linux kernel

Ubuntu raspi kernel is modified to produce an RT Linux kernel. Ubuntu is a ROS 2 Tier 1 platform and Ubuntu kernel was selected to align to it. It is possible to build the raspi kernel for Ubuntu LTS release 24.04.

Download ready-to-use RT Kernel deb packages

RT Kernel is configured using configuration parameters from the file. In the case you need to build your own kernel read the description below.

Using GUI

Go to the Action tab, find the Build stable, go inside the latest workflow run, download, and unzip artifacts called RPI4 RT Kernel deb packages. This archive contains three debian packages. Follow instructions to deploy them on the RPI.

Using command line

Go to the Developer settings and generate a token to access the repo via Github API. Use this token in conjunction with your Github name to retrieve build artifacts.

$ token=<my_token>
# rertieve all artifacts
$ curl -i -u <my github name>:$token -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/ros-realtime/linux-real-time-kernel-builder/actions/artifacts | grep archive_download_url
      "archive_download_url": "https://api.github.com/repos/ros-realtime/linux-real-time-kernel-builder/actions/artifacts/91829081/zip",
      "archive_download_url": "https://api.github.com/repos/ros-realtime/linux-real-time-kernel-builder/actions/artifacts/91534731/zip",

# download the latest one
$ curl -u <my github name>:$token -L -H "Accept: application/vnd.github.v3+json"  https://api.github.com/repos/ros-realtime/linux-real-time-kernel-builder/actions/artifacts/91829081/zip  --output rpi4_rt_kernel.zip

$ unzip rpi4_rt_kernel.zip

Raspberry Pi RT Linux kernel build

Ubuntu 24.04 x86_64 based Dockerfile is developed to cross-compile a new kernel.

Build environment

Docker container comes with cross-compilation tools installed, and a ready-to-build RT Linux kernel:

  • ARMv8 cross-compilation tools
  • Linux source build dependencies
  • Linux source buildinfo, from where kernel config is copied
  • Ubuntu raspi Linux source installed under ~/linux_build
  • RT kernel patch downloaded and applied - the nearest to the recent raspi Ubuntu kernel

It finds the latest raspi linux-image and the closest to it RT patch. If the build arguments specified it will build a corresponding kernel version instead.

Build and run docker container

For the local build:

git clone https://github.com/ros-realtime/linux-real-time-kernel-builder
cd linux-real-time-kernel-builder
docker build [--no-cache] [--build-arg UBUNTU_VERSION=<ubuntu name>] [--build-arg KERNEL_VERSION=<kernel version>] [--build-arg UNAME_R=<raspi release>] [--build-arg RT_PATCH=<RT patch>] [--build-arg LTTNG_VERSION=<LTTNG version>] -t rtwg-image .

where:

  • <ubuntu name> is noble, default is noble
  • <kernel version> is 6.8.0, default is 6.8.0
  • <raspi release> is in a form of 6.8.0-1005-raspi, see Ubuntu raspi Linux kernels
  • <RT patch> is in a form of 6.8.2-rt11, see RT patches
  • <LTTNG version> is 2.13, default is 2.13
docker run -t -i rtwg-image bash

Kernel configuration

There is a separate kernel configuration fragment.config-fragment introduced to apply ROS2 real-time specific kernel settings. Below is an example:

$ cat .config-fragment
CONFIG_PREEMPT_RT=y
CONFIG_NO_HZ_FULL=y
CONFIG_HZ_1000=y
# CONFIG_AUFS_FS is not set

If you need to reconfigure it, run

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

Alternatively, you can modify .config-fragment and then merge your changes in the .config by running

cd $HOME/linux_build/linux-raspi
ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- ./scripts/kconfig/merge_config.sh .config $HOME/linux_build/.config-fragment

Kernel build

cd $HOME/linux_build/linux-raspi
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LOCALVERSION=-raspi -j `nproc` bindeb-pkg

You need 16GB free disk space to build it, it takes a while, and the results are located:

raspi:~/linux_build/linux-raspi $ ls -la ../*.deb
-rw-r--r-- 1 user user   9355162 Jul  1 16:44 ../linux-headers-6.8.4-rt11-raspi_6.8.4-g75867ff0890f-4_arm64.deb
-rw-r--r-- 1 user user  70457678 Jul  1 16:44 ../linux-image-6.8.4-rt11-raspi_6.8.4-g75867ff0890f-4_arm64.deb
-rw-r--r-- 1 user user   1377154 Jul  1 16:44 ../linux-libc-dev_6.8.4-g75867ff0890f-4_arm64.deb

Deploy new kernel on Raspberry Pi

Download and install Ubuntu 24.04 server image

Follow these links to download and install Ubuntu 24.04 on your Raspberry Pi

# initial username and password
ubuntu/ubuntu

Update your system

After that you need to connect to the Internet and update your system

$ sudo apt-get update && apt-get upgrade

Install Ubuntu Desktop (optional)

Optionally you can install a desktop version

$ sudo apt-get update && apt-get upgrade && apt-get install ubuntu-desktop

Copy a new kernel to your system and install it

Assumed you have already copied all *.deb kernel packages to your $HOME directory

cd $HOME
sudo dpkg -i linux-image-*.deb

sudo reboot

After reboot you should see a new RT kernel installed and real-time enabled

ubuntu@ubuntu:~$ uname -a
Linux ubuntu 6.8.4-rt11-raspi #1 SMP PREEMPT_RT Mon Jul 1 14:10:16 UTC 2024 aarch64 aarch64 aarch64 GNU/Linux

ubuntu@ubuntu:~$ cat /sys/kernel/realtime
1

Intel UP2 board RT kernel build

To build x86_64 Linux kernel, see Building Realtime rt_preempt kernel for ROS 2

Why is LTTng included in the kernel?

LTTng stands for Linux Trace Toolkit: next generation and is an open source toolkit that enables low-level kernel tracing which can be extremely useful when calculating callback times, memory usage and many other key characteristics.

As this repository is within the ros-realtime organization it can be assumed that most users will install ROS 2 on the end system - which then they can use ros2_tracing to trace various things. Since ros2_tracing uses LTTng as its tracer, and since the lttng-modules package is not easily available for the raspberry-pi RT linux kernel we build it into the kernel here as a work around.

References