Appearance
5. Kernel Compilen
Übersicht zu Komponenten und Versionen
| Name | Version | Link |
|---|---|---|
| Ubuntu | 24.04 LTS | link |
| Raspberry Pi OS Bookworm | Raspberry Pi OS Lite | link |
| Linux Kernel | rpi-6.6.y | link |
| ARM gcc Toolchain (Raspi 4) | 14.2.Rel1 | link |
| ARM AARCH64 gcc Toolchain (Raspi 5) | 14.2.Rel1 | link |
| Virtualbox | 7.1.6 | link |
| Buildroot | 2024.11.1 | link |
Linux Kernel
Der Linux kernel wird vom Kernel Team über git verwaltet. Versionen und das Repository sind unter https://www.kernel.org/ ersichtlich.
Für das Raspberry Pi existiert ein eigenes Git Repository https://github.com/raspberrypi/linux, in welchem die Raspberry Pi foundation ihren eigenen vom Vanilla abgeleiteten Kernel zur Verfügung stellt. Allgemein gilt: weil der Kernel unter GPL lizenziert ist, muss der Source Code des Kernels inklusive allen Änderungen für User unter der GPL verfügbar sein.
Für unsere Versuche basieren wir auf dem LTS Release Branch rpi-6.6.y.
Frage
Welchen Kernel haben wir mit Buildroot verwendet? Kann dies im laufenden Betrieb des Targets ermittelt werden?
Toolchain aufsetzen
In Buildroot haben wir den Kernel bereits mit der Toolchain (von Buildroot heruntergeladen) kompiliert und auf die Bootpartition deployt.
Produkte des Kernels sind:
- self extracting Kernel Image
zImage(je nach Bootloader z.T.uImage) - Kernelmodule welche nicht statisch gelinkt sind (
*.ko) - Device Tree Binding
.dtbfür das Raspberry Pi - Device Tree Overlays für peripherie
*.dto.
Um den Kernel für das Target kompilieren zu können, hat Buildroot für uns die passende Toolchain verwendet.
Wir laden nun einen aktuellen Release der arm Toolchain für unser Hostsystem und das Linux Arm 32 Target herunter.
Besuchen Sie hierfür https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads und suchen Sie die passende Toolchain aus. Welche wird wohl am besten zu unserem Target passen?
Toolchain
Wählen Sie Linux Hosted x86-64 und AArch32 GNU/Linux target with hard float (arm-none-linux-gnueabihf) fürs Raspi 4 und AArch64 GNU/Linux target (aarch64-none-linux-gnu) fürs Raspi 5.
Auswahl für die Versuche
Verwenden Sie ARM gcc Toolchain (Raspi 4) füs Raspi 4 und ARM AARCH64 gcc Toolchain (Raspi 5) fürs Raspi 5.
Entpacken Sie die Toolchain im Downloads folder und erstellen Sie einen Symbolischen link mit ln auf den Folder
Wechseln zuerst Sie in das Verzeichnis ~/edev. Validieren Sie, dass die Toolchain arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz / arm-gnu-toolchain-14.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz im Ordner ~/Downloads heruntergeladen worden ist.
bash
# symbolic link auf die toolchain im working directory
ln -s ~/Downloads/<hier-das-toolchain-directory> toolchain
# ls -al sollte nun einen symbolischen link auf die toolchain zeigen
ls -alProbleme beim Kompilieren
Es kann sein, dass mit einer sehr aktuellen Toolchain Probleme beim Compilen entstehen, wie z.B.
drivers/media/i2c/msp3400-driver.c:421:17: internal compiler error: Illegal instruction
421 | msp3400c_set_carrier(client, MSP_CARRIER(10.7),Hier ein Beispiel eines Fehlers mit gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf. https://community.arm.com/support-forums/f/compilers-and-libraries-forum/52623/gcc-11-2-arm-none-eabi-internal-compiler-error-illegal-instruction/176970
Environment Variablen setzen
Für das Compilen müssen noch folgende Variablen gesetzt sein: ARCH=arm und CROSS_COMPILE soll den ganzen Prefix von ARM-gcc inklusive absolutem Pfad beinhalten.
In unserem Fall wäre das /home/$USER/edev/toolchain/bin/arm-none-linux-gnueabihf- oder /home/$USER/edev/toolchain/bin/aarch64-none-linux-gnu-. Wichtig ist das - am Ende des Pfades.
Mit export können die Variablen ins environment aufgenommen werden. Führen Sie also im Terminal aus:
Raspi 4export CROSS_COMPILE=/home/$USER/edev/toolchain/bin/arm-none-linux-gnueabihf- und export ARCH=arm.
Raspi 5export CROSS_COMPILE=/home/$USER/edev/toolchain/bin/arm-none-linux-gnueabihf- und export ARCH=arm64.
Kontrollieren Sie ob die Pfade stimmen mit
bash
echo $CROSS_COMPILE
echo $ARCHAchtung: neues Terminal
Sobald Sie das Terminal verlassen gehen die Variablen verloren!
Sie können dieses Setup allerdings auch in einem Shell Script (z.B. envsetup.sh) durchführen. Damit die Änderungen am Environment auch ausserhalb des Scripts übernommen werden, müssen Sie dieses allerdings mit source aufrufen.
bash
#!/usr/bin/bash
# file envsetup.sh
export ARCH=arm
export CROSS_COMPILE=<toolchain-prefix>bash
# env aufsetzen mit
source envsetup.sh
# alternativ mit
. envsetup.shSetup Testen
Falls alles geklappt hat wird dieser Command ARM GCC aufrufen:
bash
${CROSS_COMPILE}gcc -vKernel Sources via git herunterladen
Wir laden die Kernel Sources von dem Raspberry Pi git repository herunter. Mit git clone können wir entweder den ganzen Tree mit der ganzen Kernel History herunterladen oder alternativ nur den aktuellen branch verwenden:
Wechseln Sie ins Verzeichnis ~/edev. Verwenden Sie für <branch> rpi-6.6.y
bash
# linux-rpi: lokales verzeichnis
git clone --depth 1 --single-branch --branch <branch> https://github.com/raspberrypi/linux.git linux-rpiKernel kompilieren
Ein typischer Vorgang für das kompilieren und deployen eines Kernels sieht so aus:
- Kernel herunterladen
- Toolchain einrichten
- ggf. Kernel patchen
- Board
defconfignach.configkopieren. - Menuconfig ausführen und Treiber auswählen mit
make menuconfig make zImagemake modulesmake dtbszImageunddtbkopieren und Bootloader konfigurieren für neues image..komodules ins RFS kopieren unter entsprechendem Folder.- DT Overlays in die Boot Partition kopieren und Bootloader konfigurieren.
Menuconfig
Wechseln Sie in das Verzeichnis des Kernel Sources edev/linux-rpi.
Zuerst laden wir die defconfig für unseren SoC:
bash
# Raspi 4
make bcm2711_defconfigbash
# Raspi 5
make bcm2712_defconfigInstallieren Sie noch folgende Pakete:
sudo apt install libmpc-dev \
flex bison openssl libssl-devFür den Moment patchen wir den Kernel nicht und selektieren neu IIO Treiber und linken dies statisch dem Kernel hinzu (in menuconfig mit [*]).
Führen Sie make menuconfig aus um die Menuconfig zu starten.

XZ komprimierte Module
Suchen Sie in der Config nach der Option MODULE_COMPRESS_XZ und setzen Sie diese auf n. Verwenden Sie / im Menü um einen Suchbegriff einzugeben. Neben den Suchresultaten finden Sie Nummerierung, welche Sie direkt zur Option führt.
Wechseln Sie ins Verzeichnis des Kernels und suchen Sie mit ? nach IIO und aktivieren Sie die Treiber für den Pressure Sensor und Humidity Sensor, den Sie hier finden https://pinout.xyz/pinout/sense_hat. Verwenden Sie wieder ? in der menuconfig um die Sensormodelle zu finden.
Verlassen Sie das Menü und speichern Sie die Config.
Compile
Kompilieren Sie den Kernel mit make zImage dtbs modules.
Das kompilieren wird eine Zeit dauern. Als Referenz auf einem 16 Thread Ryzen CPU dauert es ca 10 Minuten mit 15 Threads.
Mit -j15 können so bei make mehrere Threads verwendet werden. Um die Zeit zu messen können Sie mit time den make Command aufrufen:
bash
# -jX: X am besten Anzahl Threads der CPU - 1
# rpi4
time make -j15 zImage dtbs modules
# rpi 5
time make -j15 Image dtbs modulesDeploy
Kopieren Sie die Produkte des Kernels an die entsprechenden Orte auf dem Target
Raspi 4
| Source | Partition | Destination | |
|---|---|---|---|
arch/arm/boot/zImage | Kernel | Boot | zImage |
arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dtb | Device Tree Blob | Boot | bcm2711-rpi-4-b.dtb |
arch/arm/boot/dts/overlays/*.dtb* | Overlay Tree | Boot | overlays |
*.ko | Kernelmodule | RFS | /lib/modules/** |
Raspi 5
| Source | Partition | Destination | |
|---|---|---|---|
arch/arm64/boot/Image | Kernel | Boot | Image |
arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dtb | Device Tree Blob | Boot | bcm2712-rpi-5-b.dtb |
arch/arm/boot/dts/overlays/*.dtb* | Overlay Tree | Boot | overlays |
*.ko | Kernelmodule | RFS | /lib/modules/** |
Für die Kernelmodule *.ko verwenden wir make, da auch Unterverzeichnissen erstellt werden:
bash
# Pfad für rootfs ggf. anpassen
sudo make ARCH=arm INSTALL_MOD_PATH=/media/$USER/rootfs/ modules_installNach dem kopieren können Sie die SD-Karte unmounten und das Raspberry Pi neu starten. Kontrollieren Sie mit cat /proc/version, dass Sie den neuen Kernel richtig installiert haben.