Buildroot Image mit QEMU booten

14. Juni 2019

Will man Linux auf Mikroprozessoren zum Laufen bringen, dann kommt man mit den 0815 Linux-Distributionen nicht weit. Wenn es nicht schon an der Architektur scheitert, scheitert es i.d.R. an den zu generischen und damit zu großen Paketen (Programme, Bibliotheken). Eingebettete Systeme bringen nun mal nicht sonderlich viele Resourcen mit. Folglich muss man sich sein Linux-Betriebssystem selber bauen. Dazu bieten sich mehrere Möglichkeiten kann:

Grundvoraussetzungen

Damit überhaupt Programme kompiliert werden können, braucht es ein Bündel an Programmen und Bibliotheken. Unter auf Debian basierenden Distributionen installiert man diese für gewöhnlich folgendermaßen.

$ sudo apt install build-essential

Weiterhin wird später noch QEMU verwendet werden, das gleich mitinstalliert werden kann.

$ sudo apt install qemu-system-arm

buildroot vorbereiten

In Anleitungen (Offizielle Dokumentation) findet sich häufig folgender Aufruf,

$ git clone git://git.buildroot.net/buildroot

aber das Repository scheint verschoben worden zu sein.

$ git clone git://git.busybox.net/buildroot

Standardmäßig wird der master Branch ausgecheckt, der nicht als stabil angesehen werden kann. Deshalb checkt man ein Release aus. Eine Liste der vorhandenen Releases bekommt man mit

$ git tag -l
..
2018.11.1
2018.11.2
2018.11.3
2018.11.4
2019.02
2019.02-rc1
2019.02-rc2
2019.02-rc3
2019.02.1
2019.02.2
2019.05
2019.05-rc1
2019.05-rc2
2019.05-rc3

und ausgecheckt werden sie so:

$ git checkout -b NeuerArbeitsBranch 2019.05
Switched to a new branch 'NeuerArbeitsBranch'

Wenn man sich nicht sicher ist, ob nicht schon Einstellungen vorgenommen wurden, kann man diese mit

$ make clean
$ make distclean

zurücksetzen. Dabei entfernt clean alle von buildroot angelegten Dateien und distclean alle Konfigurationsdateien.

buildroot anschmeißen

Zur Konfiguration werde ich mich an anderer Stelle detaillierter äußern, um erst einmal loslegen zu können, genügt ein Rückgriff auf eine vorhandene Standardkonfiguration. Im Falle von ARM ist es die qemu_arm_versatile_defconfig für einen arm926t und qemu_arm_vexpress_defconfig für einen Cortex-A9. Um mehrere Konfigurationen gleichzeitig nebeneinander verwalten zu können, bedarf es verschiedener Build-Ordner. Dafür muss man einzig den Parameter O= setzen.

Aus

$ make qemu_arm_versatile_defconfig

wird so

$ make O=../QemuArmVersatile qemu_arm_versatile_defconfig

Der Befehl kopiert nur die Konfigurationsdatei .config in den angegebenen Ordner. Mit

$ make O=../QemuArmVersatile

wird der Buildprozess gestartet.

Aus

$ make qemu_arm_vexpress_defconfig

wird so

$ make O=../QemuArmVexpress qemu_arm_vexpress_defconfig

Der Befehl kopiert nur die Konfigurationsdatei .config in den angegebenen Ordner. Mit

$ make O=../QemuArmVexpress

wird der Buildprozess gestartet.

Das kann etwas dauern, da in dieser Konfiguration z.B. der Compiler (gcc) explizit übersetzt wird und nicht auf einen eventuell vorhandenen Cross-Compiler des Host-Systems zurückgegriffen wird.

Nach dem erfolgreichen Durchlauf sieht der Ordner QemuArmVersatile (bzw. der Ordner QemuArmVexpress) folgendermaßen aus.

$ tree -L 2
.
├── build
│   ├── buildroot-config
│   ├── buildroot-fs
│   ├── build-time.log
│   ├── busybox-1.30.1
│   ├── host-acl-2.2.53
│   ├── host-attr-2.4.48
│   ├── host-autoconf-2.69
│   ├── host-automake-1.15.1
│   ├── host-binutils-2.31.1
│   ├── host-bison-3.0.4
│   ├── host-e2fsprogs-1.44.5
│   ├── host-fakeroot-1.20.2
│   ├── host-flex-2.6.4
│   ├── host-gcc-final-7.4.0
│   ├── host-gcc-initial-7.4.0
│   ├── host-gettext
│   ├── host-gettext-tiny-c6dcdcdef801127549d3906d153c061880d25a73
│   ├── host-gmp-6.1.2
│   ├── host-kmod-25
│   ├── host-libtool-2.4.6
│   ├── host-libzlib-1.2.11
│   ├── host-m4-1.4.18
│   ├── host-makedevs
│   ├── host-mpc-1.1.0
│   ├── host-mpfr-4.0.2
│   ├── host-patchelf-0.9
│   ├── host-pkgconf-1.6.1
│   ├── host-skeleton
│   ├── host-tar-1.29
│   ├── host-util-linux-2.33
│   ├── host-zlib
│   ├── ifupdown-scripts
│   ├── initscripts
│   ├── linux-4.19.16
│   ├── linux-headers-4.19.16
│   ├── locales.nopurge
│   ├── packages-file-list-host.txt
│   ├── packages-file-list-staging.txt
│   ├── packages-file-list.txt
│   ├── qemu_arm_versatile
│   ├── skeleton
│   ├── skeleton-init-common
│   ├── skeleton-init-sysv
│   ├── toolchain
│   ├── toolchain-buildroot
│   └── uclibc-1.0.31
├── host
│   ├── arm-buildroot-linux-uclibcgnueabi
│   ├── bin
│   ├── etc
│   ├── include
│   ├── lib
│   ├── lib64 -> lib
│   ├── libexec
│   ├── sbin
│   ├── share
│   └── usr -> .
├── images
│   ├── rootfs.ext2
│   ├── versatile-pb.dtb
│   └── zImage
├── Makefile
├── staging -> host/arm-buildroot-linux-uclibcgnueabi/sysroot
└── target
    ├── bin
    ├── dev
    ├── etc
    ├── lib
    ├── lib32 -> lib
    ├── linuxrc -> bin/busybox
    ├── media
    ├── mnt
    ├── opt
    ├── proc
    ├── root
    ├── run
    ├── sbin
    ├── sys
    ├── THIS_IS_NOT_YOUR_ROOT_FILESYSTEM
    ├── tmp
    ├── usr
    └── var

72 directories, 11 files

Von Interesse sind in erster Linie die Dateien Ordner images. Dort liegt das Dateisystem rootfs.ext, der device tree versatile-pb.dtb (bzw. vexpress-v2p-ca9.dtb) in seiner kompilierten Form und der Kernel zImage.

QEMU starten

Das eben erstellte Image kann nun mit QEMU ausgeführt werden. Da QEMU einige Parameter übergeben werden müssen, packt man den Aufruf der Einfachheit halber in ein Skript.

Dieses Skript legt man außerhalb von QemuArmVersatile ab, schließlich kann und wird sich am Image noch etwas ändern.

#!/bin/sh

qemu-system-arm \
	-M versatilepb \
	-kernel QemuArmVersatile/images/zImage \
	-dtb QemuArmVersatile/images/versatile-pb.dtb \
	-drive file=QemuArmVersatile/images/rootfs.ext2,if=scsi,format=raw \
	-append "root=/dev/sda console=ttyAMA0,115200" \
	-serial stdio \
	-net nic,model=rtl8139 -net user \
	-name Versatile_ARM_EXT2

Führt man das Skript aus, so sollte der Bootvorgang starten und folgende Ausgaben erscheinen.

Dieses Skript legt man außerhalb von QemuArmVexpress ab, schließlich kann und wird sich am Image noch etwas ändern.

#!/bin/sh

qemu-system-arm \
	-M vexpress-a9 \
	-kernel QemuArmVexpress/images/zImage \
	-dtb QemuArmVexpress/images/vexpress-v2p-ca9.dtb \
	-drive file=QemuArmVexpress/images/rootfs.ext2,if=sd,format=raw \
	-append "rw console=ttyAMA0 console=tty root=/dev/mmcblk0" \
	-cpu cortex-a9 \
	-m 32 \
	-serial stdio \
	-net nic,model=lan9118 \
	-net user \
	-name Vexpress_ARM

Führt man das Skript aus, so sollte der Bootvorgang starten und folgende Ausgaben erscheinen.

Das System funktioniert, fehlt noch das Einspielen und Debuggen der eigenen Applikation, was in einem separaten Beitrag behandelt wird.

Blobs vs spezifische Befehle

1. Mai 2020

Liederliste aus Radiostream extrahieren

22. November 2019

csv nach png

15. Oktober 2019