├── .config-fragment ├── .github └── workflows │ ├── build-latest.yml │ ├── build-stable.yaml │ └── rpi4-kernel-build.yml ├── Dockerfile ├── LICENSE ├── README.md └── getpatch.sh /.config-fragment: -------------------------------------------------------------------------------- 1 | CONFIG_VIRTUALIZATION=n 2 | CONFIG_PREEMPT_RT=y 3 | CONFIG_LOCKUP_DETECTOR=n 4 | CONFIG_DETECT_HUNG_TASK=n 5 | CONFIG_NO_HZ_FULL=y 6 | CONFIG_HZ_1000=y 7 | # CONFIG_AUFS_FS is not set 8 | CONFIG_CPU_FREQ=y 9 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y 10 | CONFIG_CPU_FREQ_GOV_ONDEMAND=y 11 | CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y 12 | CONFIG_CPU_IDLE=n 13 | CONFIG_LTTNG=y 14 | # CONFIG_LTTNG_EXPERIMENTAL_BITWISE_ENUM is not set 15 | # CONFIG_LTTNG_CLOCK_PLUGIN_TEST is not set 16 | CONFIG_MODULES=y 17 | CONFIG_KALLSYMS=y 18 | CONFIG_HIGH_RES_TIMERS=y 19 | CONFIG_TRACEPOINTS=y 20 | # CONFIG_KPROBES is not set 21 | CONFIG_HAVE_SYSCALL_TRACEPOINTS=y 22 | CONFIG_EVENT_TRACING=y 23 | CONFIG_PERF_EVENTS=y 24 | # CONFIG_KRETPROBES is not set 25 | # CONFIG_KALLSYMS_ALL is not set 26 | CONFIG_DEBUG_INFO=n 27 | CONFIG_IKCONFIG=y 28 | CONFIG_IKCONFIG_PROC=y 29 | CONFIG_SYSTEM_TRUSTED_KEYS="" 30 | CONFIG_SYSTEM_REVOCATION_KEYS="" 31 | -------------------------------------------------------------------------------- /.github/workflows/build-latest.yml: -------------------------------------------------------------------------------- 1 | name: 'Build latest' 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | kernel_version: 7 | description: 'Raspi kernel version, 5.4.0|5.15.0' 8 | default: '5.15.0' 9 | required: false 10 | type: string 11 | ubuntu_version: 12 | description: 'Ubuntu version, focal|jammy' 13 | default: 'jammy' 14 | required: false 15 | type: string 16 | lttng_version: 17 | description: 'LTTNG version, 2.13' 18 | default: '2.13' 19 | required: false 20 | type: string 21 | 22 | jobs: 23 | call-rpi4-kernel-build: 24 | uses: ./.github/workflows/rpi4-kernel-build.yml 25 | with: 26 | kernel_version: ${{ github.event.inputs.kernel_version }} 27 | ubuntu_version: ${{ github.event.inputs.ubuntu_version }} 28 | lttng_version: ${{ github.event.inputs.lttng_version }} 29 | -------------------------------------------------------------------------------- /.github/workflows/build-stable.yaml: -------------------------------------------------------------------------------- 1 | name: 'Build stable' 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | kernel_version: 7 | description: 'Raspi kernel version, 6.8.0' 8 | default: '6.8.0' 9 | required: false 10 | type: string 11 | ubuntu_version: 12 | description: 'Ubuntu version, jammy|noble' 13 | default: 'noble' 14 | required: false 15 | type: string 16 | uname_r: 17 | description: 'raspi release in the form of <6.8.0-1005-raspi>' 18 | required: true 19 | default: '6.8.0-1005-raspi' 20 | type: string 21 | lttng_version: 22 | description: 'LTTNG version 2.13' 23 | default: '2.13' 24 | required: false 25 | type: string 26 | jobs: 27 | call-rpi4-kernel-build: 28 | uses: ./.github/workflows/rpi4-kernel-build.yml 29 | with: 30 | uname_r: ${{ github.event.inputs.uname_r }} 31 | kernel_version: ${{ github.event.inputs.kernel_version }} 32 | ubuntu_version: ${{ github.event.inputs.ubuntu_version }} 33 | lttng_version: ${{ github.event.inputs.lttng_version }} 34 | -------------------------------------------------------------------------------- /.github/workflows/rpi4-kernel-build.yml: -------------------------------------------------------------------------------- 1 | # This is a callable workflow for the Raspberry Pi RT kernel build. It is based on the Dockerfile located in the repo 2 | # Workflow can be started from another workflow 3 | # The build takes 2 hours and artifacts are available under workflow artifacts 4 | # - kernel .deb packages 5 | # TODO: 6 | # - create a Docker image and push it to the packages 7 | 8 | name: 'RPI4 RT Kernel build' 9 | 10 | # Controls when the workflow will run 11 | on: 12 | workflow_call: 13 | inputs: 14 | uname_r: 15 | description: 'raspi release in a form of <5.15.0-1023-raspi>' 16 | default: '' 17 | required: false 18 | type: string 19 | rt_patch: 20 | description: 'RT patch in a form of <5.15.76-rt53>' 21 | default: '' 22 | required: false 23 | type: string 24 | kernel_version: 25 | description: 'Raspi kernel version' 26 | default: '5.15.0' 27 | required: false 28 | type: string 29 | ubuntu_version: 30 | description: 'Ubuntu version' 31 | default: 'jammy' 32 | required: false 33 | type: string 34 | lttng_version: 35 | description: 'LTTNG version' 36 | default: '2.13' 37 | required: false 38 | type: string 39 | env: 40 | ARCH: arm64 41 | triple: aarch64-linux-gnu 42 | KERNEL_DIR: linux-raspi 43 | 44 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 45 | jobs: 46 | # This workflow contains a single job called "build" 47 | build: 48 | # Use Ubuntu 22.04 runner 49 | runs-on: ubuntu-22.04 50 | 51 | # Steps represent a sequence of tasks that will be executed as part of the job 52 | steps: 53 | # Checks-out repository under $GITHUB_WORKSPACE, so your job can access it 54 | - uses: actions/checkout@v3 55 | 56 | - name: Free Disk Space 57 | uses: jlumbroso/free-disk-space@main 58 | with: 59 | # this might remove tools that are actually needed, 60 | # if set to "true" but frees about 6 GB 61 | tool-cache: true 62 | 63 | # all of these default to true, but feel free to set to 64 | # "false" if necessary for your workflow 65 | android: true 66 | dotnet: true 67 | haskell: true 68 | large-packages: true 69 | docker-images: false 70 | swap-storage: true 71 | 72 | - name: Print input params 73 | run: | 74 | echo UBUNTU_VERSION=${{ inputs.ubuntu_version }} 75 | echo KERNEL_VERSION=${{ inputs.kernel_version }} 76 | echo UNAME_R=${{ inputs.uname_r }} 77 | echo RT_PATCH=${{ inputs.rt_patch }} 78 | echo LTTNG_VERSION=${{ inputs.lttng_version }} 79 | 80 | - name: Build rtwg-image docker image 81 | uses: docker/build-push-action@v3 82 | with: 83 | context: . 84 | build-args: | 85 | UBUNTU_VERSION=${{ inputs.ubuntu_version }} 86 | KERNEL_VERSION=${{ inputs.kernel_version }} 87 | UNAME_R=${{ inputs.uname_r }} 88 | RT_PATCH=${{ inputs.rt_patch }} 89 | LTTNG_VERSION=${{ inputs.lttng_version }} 90 | push: false 91 | tags: rtwg-image:22.04 92 | 93 | - name: Build kernel 94 | uses: addnab/docker-run-action@v3 95 | with: 96 | image: rtwg-image:22.04 97 | options: -v ${{ github.workspace }}:/work 98 | run: | 99 | cd /linux_build/linux-raspi 100 | make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LOCALVERSION=-raspi -j `nproc` bindeb-pkg 101 | sudo cp ../*.deb /work 102 | 103 | - uses: actions/upload-artifact@v4 104 | with: 105 | name: 'RPI4 RT Kernel deb packages' 106 | path: ${{ github.workspace }}/*.deb 107 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # A Dockerfile to build an RT kernel for the Raspberry Pi based on Ubuntu 24.04 2 | # 3 | # If run without parameters the Docker image is created to built RT_PREEMPT patched version of the latest 6.8 raspi kernel 4 | # The Docker build command accepts the following build arguments: 5 | # $ docker build [--build-arg UBUNTU_VERSION=] [--build-arg KERNEL_VERSION=] 6 | # [--build-arg UNAME_R=] [--build-arg RT_PATCH=] 7 | # [--build-arg LTTNG_VERSION=] -t rtwg-image . 8 | # 9 | # where 10 | # is noble, default is noble 11 | # is in a form of 6.8.0, default is 6.8.0 12 | # is in a form of 6.8.0-1005-raspi, if not defined the lastest version is taken 13 | # see http://ports.ubuntu.com/pool/main/l/linux-raspi/ 14 | # is in a form of 6.8.2-rt11, if not defined the closest to the defined is taken 15 | # see https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.8/ 16 | # is 2.13, default is 2.13 17 | # 18 | # To build a Docker image for the latest raspi kernel, run 19 | # $ docker build -t rtwg-image . 20 | # 21 | # To build a Docker image for the stable raspi kernel, run 22 | # $ docker build --build-arg UBUNTU_VERSION=noble --build-arg KERNEL_VERSION=6.8.0 --build-arg UNAME_R=6.8.0-1005-raspi -t rtwg-image . 23 | # 24 | # After that the Docker image is prepared and ready to run 25 | # $ docker run -it rtwg-image bash 26 | # 27 | # and then inside the docker 28 | # $ cd /linux_build/linux-raspi 29 | # $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LOCALVERSION=-raspi -j `nproc` bindeb-pkg 30 | # 31 | # user /linux_build/linux-raspi $ ls -la ../*.deb 32 | # -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 33 | # -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 34 | # -rw-r--r-- 1 user user 1377154 Jul 1 16:44 ../linux-libc-dev_6.8.4-g75867ff0890f-4_arm64.deb 35 | # 36 | # copy deb packages to the host, or directly to the Raspberry Pi target 37 | # $ scp ../*.deb @172.17.0.1:/home//. 38 | 39 | FROM ubuntu:noble 40 | 41 | USER root 42 | ARG DEBIAN_FRONTEND=noninteractive 43 | 44 | # setup timezone 45 | RUN echo 'Etc/UTC' > /etc/timezone \ 46 | && ln -s -f /usr/share/zoneinfo/Etc/UTC /etc/localtime \ 47 | && apt-get update && apt-get install -q -y tzdata apt-utils lsb-release software-properties-common openssh-client \ 48 | && rm -rf /var/lib/apt/lists/* 49 | 50 | ARG ARCH=arm64 51 | ARG UNAME_R 52 | ARG RT_PATCH 53 | ARG triple=aarch64-linux-gnu 54 | ARG KERNEL_VERSION=6.8.0 55 | ARG UBUNTU_VERSION=noble 56 | ARG LTTNG_VERSION=2.13 57 | ARG KERNEL_DIR=linux-raspi 58 | 59 | # setup arch 60 | RUN apt-get update && apt-get install -q -y \ 61 | gcc-${triple} \ 62 | && dpkg --add-architecture ${ARCH} \ 63 | && sed -i 's/deb h/deb [arch=amd64] h/g' /etc/apt/sources.list \ 64 | && sed -i 's/deb h/deb [arch=amd64] h/g' /etc/apt/sources.list.d/* \ 65 | && sed -i '/Components/a\Architectures: amd64' /etc/apt/sources.list.d/*.sources \ 66 | && echo "deb [arch=$ARCH] http://ports.ubuntu.com/ubuntu-ports/ $(lsb_release -s -c) main universe restricted" >> /etc/apt/sources.list.d/ubuntu-ports.list \ 67 | && echo "deb-src [arch=$ARCH] http://ports.ubuntu.com/ubuntu-ports/ $(lsb_release -s -c) main universe restricted" >> /etc/apt/sources.list.d/ubuntu-ports.list \ 68 | && echo "deb [arch=$ARCH] http://ports.ubuntu.com/ubuntu-ports $(lsb_release -s -c)-updates main universe restricted" >> /etc/apt/sources.list.d/ubuntu-ports.list \ 69 | && rm -rf /var/lib/apt/lists/* 70 | 71 | # setup environment 72 | ENV LANG=C.UTF-8 73 | ENV LC_ALL=C.UTF-8 74 | ENV UID=1000 75 | ENV GID=1000 76 | 77 | # install build deps 78 | RUN apt-get update && apt-get build-dep -q -y linux \ 79 | && apt-get install -q -y \ 80 | libncurses-dev flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf \ 81 | fakeroot \ 82 | && rm -rf /var/lib/apt/lists/* 83 | 84 | # remove ubuntu user to set our own 85 | RUN userdel -r ubuntu 86 | 87 | # setup user 88 | RUN apt-get update && apt-get install -q -y sudo \ 89 | && groupadd -g $GID user \ 90 | && useradd -m -d /home/user -s /bin/bash -u $UID -g $GID user \ 91 | && gpasswd -a user sudo \ 92 | && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \ 93 | && echo 'user\nuser\n' | passwd user \ 94 | && rm -rf /var/lib/apt/lists/* 95 | 96 | # install extra packages needed for the patch handling 97 | RUN apt-get update && apt-get install -q -y wget curl gzip git bash-completion time \ 98 | && rm -rf /var/lib/apt/lists/* 99 | 100 | # install lttng dependencies 101 | RUN sudo apt-get update \ 102 | && sudo apt-get install -y libuuid1 libpopt0 libxml2 numactl 103 | 104 | # Create a directory and set permissions 105 | RUN mkdir -p /linux_build && chown user:user /linux_build 106 | 107 | # Define the volume 108 | VOLUME /linux_build 109 | 110 | USER user 111 | 112 | # find the latest UNAME_R and store it locally for the later usage 113 | # if $UNAME_R is set via --build-arg, take it 114 | RUN if test -z $UNAME_R; then UNAME_R=`curl -s http://ports.ubuntu.com/pool/main/l/linux-raspi/ | grep linux-buildinfo | grep -o -P '(?<=l)' | grep ${ARCH} | grep ${KERNEL_VERSION} | sort | tail -n 1 | cut -d '-' -f 3-4`-raspi; fi \ 115 | && echo $UNAME_R > /home/user/uname_r 116 | 117 | # Set the working directory 118 | WORKDIR /linux_build 119 | 120 | # install linux sources from git 121 | RUN git config --global https.postBuffer 1048576000 \ 122 | && git clone -b master --depth 1 --single-branch --jobs=$(($(nproc) * 2)) --progress https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux-raspi/+git/${UBUNTU_VERSION} ${KERNEL_DIR} \ 123 | && cd ${KERNEL_DIR} \ 124 | && git fetch --tag 125 | 126 | # checkout necessary tag 127 | RUN cd /linux_build/${KERNEL_DIR} \ 128 | && git tag -l *`cat /home/user/uname_r | cut -d '-' -f 2`* | sort -V | tail -1 > /linux_build/tag \ 129 | && git checkout `cat /linux_build/tag` 130 | 131 | # install buildinfo to retrieve `raspi` kernel config 132 | RUN cd /home/user \ 133 | && wget http://ports.ubuntu.com/pool/main/l/linux-raspi/linux-buildinfo-${KERNEL_VERSION}-`cat /home/user/uname_r | cut -d '-' -f 2`-raspi_${KERNEL_VERSION}-`cat /linux_build/tag | cut -d '-' -f 4`_${ARCH}.deb \ 134 | && dpkg -X *.deb /home/user/ 135 | 136 | COPY ./getpatch.sh /home/user/ 137 | 138 | # get the nearest RT patch to the kernel SUBLEVEL 139 | # if $RT_PATCH is set via --build-arg, take it 140 | RUN cd /linux_build/${KERNEL_DIR} \ 141 | && if test -z $RT_PATCH; then /home/user/getpatch.sh `make kernelversion` > /home/user/rt_patch; else echo $RT_PATCH > /home/user/rt_patch; fi 142 | 143 | # download and unzip RT patch 144 | RUN cd /linux_build \ 145 | && wget http://cdn.kernel.org/pub/linux/kernel/projects/rt/`echo ${KERNEL_VERSION} | cut -d '.' -f 1-2`/older/patch-`cat /home/user/rt_patch`.patch.gz \ 146 | && gunzip patch-`cat /home/user/rt_patch`.patch.gz 147 | 148 | # download lttng source for use later 149 | RUN cd /home/user/ \ 150 | && sudo apt-add-repository -s -y ppa:lttng/stable-${LTTNG_VERSION} \ 151 | && sudo apt-get update \ 152 | && apt-get source lttng-modules-dkms 153 | 154 | # run lttng built-in script to configure RT kernel 155 | RUN set -x \ 156 | && cd `ls -d /home/user/lttng-modules-*` \ 157 | && ./scripts/built-in.sh /linux_build/${KERNEL_DIR} 158 | 159 | # patch kernel, do not fail if some patches are skipped 160 | RUN cd /linux_build/${KERNEL_DIR} \ 161 | && OUT="$(patch -p1 --forward < ../patch-`cat $HOME/rt_patch`.patch)" || echo "${OUT}" | grep "Skipping patch" -q || (echo "$OUT" && false); 162 | 163 | # setup build environment 164 | RUN cd /linux_build/${KERNEL_DIR} \ 165 | && export $(dpkg-architecture -a${ARCH}) \ 166 | && export CROSS_COMPILE=${triple}- \ 167 | && fakeroot debian/rules clean \ 168 | && LANG=C fakeroot debian/rules printenv 169 | 170 | COPY ./.config-fragment /linux_build/. 171 | 172 | # config RT kernel and merge config fragment 173 | RUN cd /linux_build/${KERNEL_DIR} \ 174 | && cp /home/user/usr/lib/linux/`cat /home/user/uname_r`/config .config \ 175 | && ARCH=${ARCH} CROSS_COMPILE=${triple}- ./scripts/kconfig/merge_config.sh .config /linux_build/.config-fragment 176 | 177 | RUN cd /linux_build/${KERNEL_DIR} \ 178 | && fakeroot debian/rules clean 179 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Build ```RT_PREEMPT``` kernel for Raspberry Pi 2 | 3 | [![RPI RT Kernel build](https://github.com/ros-realtime/linux-real-time-kernel-builder/actions/workflows/rpi4-kernel-build.yml/badge.svg)](https://github.com/ros-realtime/linux-real-time-kernel-builder/actions/workflows/rpi4-kernel-build.yml) 4 | 5 | ## Introduction 6 | 7 | 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-configuration). Kernel is built automatically by the Github action, and the artifacts are located under the [```build stable```](https://github.com/ros-realtime/linux-real-time-kernel-builder/actions/workflows/build-stable.yaml). Please follow [installation instructions](#deploy-new-kernel-on-raspberry-pi) to deploy a new kernel to the RPI board. 8 | 9 | ## Raspberry Pi RT Linux kernel 10 | 11 | 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. 12 | 13 | ## Download ready-to-use RT Kernel ```deb``` packages 14 | 15 | RT Kernel is configured using configuration parameters from the [](.config-fragment) file. In the case you need to build your own kernel read the description below. 16 | 17 | ### Using GUI 18 | 19 | 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](#deploy-new-kernel-on-raspberry-pi) to deploy them on the RPI. 20 | 21 | ### Using command line 22 | 23 | Go to the [```Developer settings```](https://github.com/settings/tokens) and generate a token to access the repo via Github API. Use this token in conjunction with your Github name to retrieve build artifacts. 24 | 25 | ```bash 26 | $ token= 27 | # rertieve all artifacts 28 | $ curl -i -u :$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 29 | "archive_download_url": "https://api.github.com/repos/ros-realtime/linux-real-time-kernel-builder/actions/artifacts/91829081/zip", 30 | "archive_download_url": "https://api.github.com/repos/ros-realtime/linux-real-time-kernel-builder/actions/artifacts/91534731/zip", 31 | 32 | # download the latest one 33 | $ curl -u :$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 34 | 35 | $ unzip rpi4_rt_kernel.zip 36 | ``` 37 | 38 | ## Raspberry Pi RT Linux kernel build 39 | 40 | Ubuntu 24.04 ```x86_64``` based ```Dockerfile``` is developed to cross-compile a new kernel. 41 | 42 | ### Build environment 43 | 44 | Docker container comes with cross-compilation tools installed, and a ready-to-build RT Linux kernel: 45 | 46 | * ARMv8 cross-compilation tools 47 | * Linux source build dependencies 48 | * Linux source ```buildinfo```, from where kernel config is copied 49 | * Ubuntu ```raspi``` Linux source installed under ```~/linux_build``` 50 | * RT kernel patch downloaded and applied - the nearest to the recent ```raspi``` Ubuntu kernel 51 | 52 | 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. 53 | 54 | ### Build and run docker container 55 | 56 | For the local build: 57 | 58 | ```bash 59 | git clone https://github.com/ros-realtime/linux-real-time-kernel-builder 60 | cd linux-real-time-kernel-builder 61 | ``` 62 | 63 | ```bash 64 | docker build [--no-cache] [--build-arg UBUNTU_VERSION=] [--build-arg KERNEL_VERSION=] [--build-arg UNAME_R=] [--build-arg RT_PATCH=] [--build-arg LTTNG_VERSION=] -t rtwg-image . 65 | ``` 66 | 67 | where: 68 | 69 | * `````` is `noble`, default is `noble` 70 | * `````` is `6.8.0`, default is `6.8.0` 71 | * `````` is in a form of `6.8.0-1005-raspi`, see [Ubuntu raspi Linux kernels](http://ports.ubuntu.com/pool/main/l/linux-raspi) 72 | * `````` is in a form of `6.8.2-rt11`, see [RT patches](https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.8/) 73 | * `````` is `2.13`, default is `2.13` 74 | 75 | ```bash 76 | docker run -t -i rtwg-image bash 77 | ``` 78 | 79 | ### Kernel configuration 80 | 81 | There is a separate kernel configuration fragment```.config-fragment``` introduced to apply ROS2 real-time specific kernel settings. Below is an example: 82 | 83 | ```bash 84 | $ cat .config-fragment 85 | CONFIG_PREEMPT_RT=y 86 | CONFIG_NO_HZ_FULL=y 87 | CONFIG_HZ_1000=y 88 | # CONFIG_AUFS_FS is not set 89 | ``` 90 | 91 | If you need to reconfigure it, run 92 | 93 | ```bash 94 | make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig 95 | ``` 96 | 97 | Alternatively, you can modify ```.config-fragment``` and then merge your changes in the ```.config``` by running 98 | 99 | ```bash 100 | cd $HOME/linux_build/linux-raspi 101 | ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- ./scripts/kconfig/merge_config.sh .config $HOME/linux_build/.config-fragment 102 | ``` 103 | 104 | ### Kernel build 105 | 106 | ```bash 107 | cd $HOME/linux_build/linux-raspi 108 | make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LOCALVERSION=-raspi -j `nproc` bindeb-pkg 109 | ``` 110 | 111 | You need 16GB free disk space to build it, it takes a while, and the results are located: 112 | 113 | ```bash 114 | raspi:~/linux_build/linux-raspi $ ls -la ../*.deb 115 | -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 116 | -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 117 | -rw-r--r-- 1 user user 1377154 Jul 1 16:44 ../linux-libc-dev_6.8.4-g75867ff0890f-4_arm64.deb 118 | ``` 119 | 120 | ## Deploy new kernel on Raspberry Pi 121 | 122 | ### Download and install Ubuntu 24.04 server image 123 | 124 | Follow these links to download and install Ubuntu 24.04 on your Raspberry Pi 125 | 126 | * [Install Ubuntu on a Raspberry Pi](https://ubuntu.com/download/raspberry-pi) 127 | * [Download Ubuntu Raspberry Pi server image](https://ubuntu.com/download/raspberry-pi/thank-you?version=24.04&architecture=server-arm64+raspi) 128 | * [Create an Ubuntu image for a Raspberry Pi on Ubuntu](https://ubuntu.com/tutorials/create-an-ubuntu-image-for-a-raspberry-pi-on-ubuntu#2-on-your-ubuntu-machine) 129 | 130 | ```bash 131 | # initial username and password 132 | ubuntu/ubuntu 133 | ``` 134 | 135 | ### Update your system 136 | 137 | After that you need to connect to the Internet and update your system 138 | 139 | ```bash 140 | $ sudo apt-get update && apt-get upgrade 141 | ``` 142 | 143 | ### Install Ubuntu Desktop (optional) 144 | 145 | Optionally you can install a desktop version 146 | 147 | ```bash 148 | $ sudo apt-get update && apt-get upgrade && apt-get install ubuntu-desktop 149 | ``` 150 | 151 | ### Copy a new kernel to your system and install it 152 | 153 | Assumed you have already copied all ```*.deb``` kernel packages to your ```$HOME``` directory 154 | 155 | ```bash 156 | cd $HOME 157 | sudo dpkg -i linux-image-*.deb 158 | 159 | sudo reboot 160 | ``` 161 | 162 | After reboot you should see a new RT kernel installed and real-time enabled 163 | 164 | ```bash 165 | ubuntu@ubuntu:~$ uname -a 166 | Linux ubuntu 6.8.4-rt11-raspi #1 SMP PREEMPT_RT Mon Jul 1 14:10:16 UTC 2024 aarch64 aarch64 aarch64 GNU/Linux 167 | 168 | ubuntu@ubuntu:~$ cat /sys/kernel/realtime 169 | 1 170 | ``` 171 | 172 | ## Intel UP2 board RT kernel build 173 | 174 | To build ```x86_64``` Linux kernel, see [Building Realtime rt_preempt kernel for ROS 2](https://docs.ros.org/en/rolling/Tutorials/Miscellaneous/Building-Realtime-rt_preempt-kernel-for-ROS-2.html) 175 | 176 | ## Why is LTTng included in the kernel? 177 | 178 | [LTTng](https://lttng.org/docs) 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. 179 | 180 | 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`](https://gitlab.com/ros-tracing/ros2_tracing) uses LTTng as its tracer, and since [the `lttng-modules` package is not easily available](https://github.com/ros-realtime/linux-real-time-kernel-builder/issues/16) for the raspberry-pi RT linux kernel we build it into the kernel here as a work around. 181 | 182 | ## References 183 | 184 | * [ROS Real-Time Working group documentation](https://ros-realtime.github.io/Guides/Real-Time-Operating-System-Setup/Real-Time-Linux/rt_linux_index.html) 185 | * [Ubuntu raspi linux images](http://ports.ubuntu.com/pool/main/l/linux-raspi) 186 | * [RT patches](https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.8/) 187 | * [Download Ubuntu raspi server image](https://ubuntu.com/download/raspberry-pi/thank-you?version=24.04&architecture=server-arm64+raspi) 188 | * [Building Realtime ```RT_PREEMPT``` kernel for ROS 2](https://docs.ros.org/en/rolling/Tutorials/Miscellaneous/Building-Realtime-rt_preempt-kernel-for-ROS-2.html) 189 | -------------------------------------------------------------------------------- /getpatch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # first argument is a kernel version, script takes sublevel and calculates the nearest patch to the provided SUBLEVEL 4 | # Kernel version 5.4.174, SUBLEVEL number is 174 5 | major_minor=5.4 6 | sublevel=174 7 | if [ $# -ne 0 ]; then 8 | major_minor=`echo $1 | cut -d '.' -f 1-2` 9 | sublevel=`echo $1 | cut -d '.' -f 3` 10 | fi 11 | 12 | # Retrieve a list of ```patch.gz``` patches, and sort them 13 | # assumed patched are in form of patch-5.4.177-rt69.patch.gz 14 | patch_list=`curl -s https://cdn.kernel.org/pub/linux/kernel/projects/rt/$major_minor/older/ | grep patch.gz | cut -d '"' -f 2 | sort -V` 15 | 16 | # go through the list and take the nearest patch to the provided SUBLEVEL number which is equal or greater 17 | sl=$sublevel 18 | for patch_item in $patch_list 19 | do 20 | sl=`echo $patch_item | cut -d '-' -f 2 | cut -d '.' -f 3` 21 | if [ -n "$sl" ] && [ "$sl" -ge "$sublevel" ]; then 22 | break 23 | fi 24 | done 25 | 26 | # check whether there are several RT patches exist with the same SUBLEVEL number, and take the latest 27 | echo "$patch_list" | tr ' ' '\n' | grep patch-$major_minor.$sl | tail -n 1 | cut -d '-' -f 2-3 | cut -d '.' -f 1-3 28 | --------------------------------------------------------------------------------