Aus Raspberry Pi Geek 04/2021

Qemu 5.2 mit verbesserter Unterstützung für Raspberry Pi (Seite 2)

Dazu benötigt es den Kernel, dessen Kommandozeile und das zum System passende DTB (Device-Tree-Binary) mit der Hardware-Beschreibung. Unabhängig davon benötigt der Rechner selbstverständlich ein SD-Karten-Image mit dem Betriebssystem. Für die RasPi-Emulation laden Sie das aktuelle Raspberry Pi OS herunter und entpacken das Image aus dem Archiv. Danach liegt eine Datei mit dem Namen 2020-08-20-raspios-buster-armhf-lite.img auf der Festplatte (je nach Version und Datum der Veröffentlichung).

Falls Sie Linux als Host-Plattform nutzen, laden Sie zusätzlich aus dem Github-Repository [3] des Autors die Skripte herunter und kopieren sie als Root ins Verzeichnis /usr/local/bin/. Danach extrahieren Sie Kernel, DTB und Kommandozeile (Listing 2, Zeile 2 – hier ist der Name des Images abgekürzt).

Listing 2

Ablauf

### Image vorbereiten
$ sudo extract_kernel.sh buster-lite.img
$ qemu-img resize buster-lite.img 4G
### Erster Boot mit Resize
$ raspi2.sh buster-lite.img
$ sudo extract_kernel.sh buster-lite.img
### Weitere Boots
$ raspi2.sh buster-lite.img
### Snapshot-Image
$ qemu-img create -f qcow2 -b buster-lite.img delta.qcow2
### Verwenden als Bootmedium
$ raspi2.sh delta.qcow2
### Virtuelle USB-Platte als Zusatzargumente
$ qemu-img create -f qcow2 hdd.qcow2 16G
$ raspi2.sh delta.qcow -drive file=hdd.qcow2,if=none,node-name=my_hdd -device usb-storage,drive=my_hdd

Windows- und Mac-Anwender haben es nicht so leicht. Am einfachsten installieren Sie das Image wie üblich auf eine echte SD-Karte und kopieren die Dateien kernel7.img sowie bcm2709-rpi-2-b.dtb und cmdline.txt zusammen mit dem ursprünglichen Image in ein eigenes Verzeichnis auf dem Rechner. Die physische SD-Karte braucht Qemu anschließend nicht mehr. Das Ergebnis sollte – egal, ob unter Linux oder einem anderen Betriebssystem – etwa so aussehen wie in Abbildung 1. Die Abbildung zeigt auch die Kernel und DTBs der anderen RasPi-Plattformen.

Abbildung 1: Um einen Raspberry Pi in Qemu zu betreiben, benötigen Sie eine Reihe von Dateien aus dem Pi-OS-Image.

Abbildung 1: Um einen Raspberry Pi in Qemu zu betreiben, benötigen Sie eine Reihe von Dateien aus dem Pi-OS-Image.

Anschließend passen Sie noch die Größe des Images an. Qemu erwartet eine SD-Karte, deren Größe eine Zweierpotenz in Gigabyte ist. Den entsprechenden Befehl zeigt die dritten Zeile von Listing 2. Hier brauchen Sie nicht zu knausern, denn der Emulator vergrößert die Datei nicht physisch. Der Befehl qemu-img info zeigt logische und physische Größe von Images an (Abbildung 2).

Abbildung 2: Virtuelle und reale Größe eines Images weichen voneinander ab, weil Qemu den Speicherplatz erst belegt, wenn es ihn wirklich benötigt.

Abbildung 2: Virtuelle und reale Größe eines Images weichen voneinander ab, weil Qemu den Speicherplatz erst belegt, wenn es ihn wirklich benötigt.

Aufruf

Bei Virtualisierern wie VMware oder Virtualbox definieren Sie die Hardware über eine GUI-Anwendung. Die Konfiguration landet dann in irgendwelchen Dateien, mit denen Sie als User nichts zu tun haben. Diesen Luxus gibt es bei Qemu nicht: Hier erfolgt die Konfiguration beim Aufruf des Emulators; entsprechend lang fällt der Befehl samt Argumenten aus.

Im Listing 3 sehen Sie ein Beispiel: Das Skript erwartet als erstes Argument den Pfad zum Image, danach folgen optional weitere Argumente für den Emulator. Im oben erwähnten Repository des Autors gibt es etwas ausgefeiltere Skripte für die verschiedenen RasPi-Boards, etwa raspi2.sh.

Listing 3

Qemu-Aufruf für den RasPi

#!/bin/bash
EXTRA_ARGS="bcm2708_fb.fbwidth=1280 bcm2708_fb.fbheight=1024 dwc_otg.fiq_fsm_enable=0"
osimg="$1"
shift
qemu-system-arm \
-machine raspi2 \
-device usb-mouse \
-device usb-kbd \
-drive file="$osimg",if=sd \
-netdev user,id=net0,hostfwd=tcp::8022-:22 \
-device usb-net,netdev=net0 \
\
-kernel "kernel7.img" \
-append "$(cat cmdline.txt) $EXTRA_ARGS" \
-dtb "bcm2709-rpi-2-b.dtb" \
\
-no-reboot \
-daemonize \
\
"${@}"

Der erste Block an Argumenten für Qemu definiert die Hardware, in diesem Fall einen RasPi 2. Normalerweise wählen Sie die Hardware-Ausstattung über Optionen wie -smp (CPU-Anzahl) oder -m (Hauptspeicher) recht detailliert. Manche Boards können sogar verschiedene CPUs emulieren (Option -cpu). Für diesen Fall brauchen Sie das alles nicht, deshalb beschränkt sich das Skript auf die Angabe von Maus, Tastatur, Netzwerk- und SD-Karte. Die Hardware-Emulation für den RasPi ist noch sehr lückenhaft, insbesondere fehlt die Onboard-Ethernet-Schnittstelle. Stattdessen kommt hier eine virtuelle USB-Netzwerkkarte zum Einsatz.

Der zweite Block gibt Qemu den zu startenden Kernel sowie die Kommandozeile und den DTB mit. Das Skript geht dabei davon aus, dass sich Image, Kernel, Kommandozeile und DTB in demselben Verzeichnis befinden. Der Standard-Kommandozeile des Kernels fügt der Aufruf noch ein paar zusätzliche Argumente hinzu: einmal die Größe des Bildschirms und einen weiteren, technisch notwendigen Parameter (Variable EXTRA_ARGS aus Zeile 2).

Mit diesen Befehlen klappt der erste Aufruf. Da die Datei cmdline.txt den Parameter quiet enthält, sehen Sie beim Booten nicht viel, aber nach einiger Zeit erscheint die bekannte Meldung, dass das System das Dateisystem auf den verfügbaren Platz erweitert. Anschließend versucht Pi OS einen Reboot, den Sie aber per Aufrufparameter (Listing 3, Zeile 19) verhindern – er würde ohnehin nicht funktionieren.

Neustart

Eine Besonderheit von Raspbian und dessen Nachfolger Pi OS ist der erste Boot. Das System erledigt dabei im Prinzip nur zwei Dinge: Es erweitert die zweite Partition auf die volle physische Größe der SD-Karte und verändert die Kommandozeile (ansonsten wäre das System in einer Endlosschleife gefangen).

Die Änderung an der Kommandozeile erfolgt allerdings innerhalb des Images und nicht in unserer Version außerhalb des Images. Linux-Anwender extrahieren daher einfach noch mal mit dem Aufruf des Skripts extract_kernel.sh die aktuelle Version der Kommandozeile. Windows- und Mac-Anwender greifen zum Editor und bearbeiten die Datei cmdline.txt von Hand. Listing 4 zeigt die alte und die neue Version, für bessere Übersicht auf mehrere Zeilen aufgeteilt. Wichtig ist, dass der verwendete Editor beim Bearbeiten keinen Umbruch einfügt, die Datei darf im Endeffekt nur eine Zeile enthalten.

Listing 4

Vor und nach dem ersten Boot

# Vor dem ersten Boot
console=serial0,115200 console=tty1 root=PARTUUID=907af7d0-02 \
rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait \
quiet init=/usr/lib/raspi-config/init_resize.sh
# Nach dem ersten Boot
console=serial0,115200 console=tty1 root=PARTUUID=07f848a8-02 \
rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 8 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben