Einleitung
Als Entwickler hat man es immer schwer, wenn man Code testen soll, der für Hardware geschrieben ist, die man nicht hat Für solche Fälle bieten sich Hardware-Emulatoren sehr gut an. Im vorliegenden Falle geht es um die Emulation einer Raspberry Pi-Maschine. Leider gibt es zur Zeit keinen Emulator, der diese Hardware komplett emulieren kann, aber man kommt immerhin schon nahe. Diese Anleitung soll dabei helfen, die ersten Schritte mit dem fli4l auf einer ARM-Plattform wie dem Raspberry Pi zu machen.
Voraussetzungen
Es wird ein Linux-Host benötigt, auf dem QEMU mit ARM-Unterstützung installiert ist. Will man die fli4l-VM später netzwerktechnisch auch ans Internet anbinden, ist es von Vorteil, wenn die WAN-Karte Teil einer Bridge ist, in die sich die VM "einklinken" kann. Wie man eine Netzwerkkonfiguration unter Linux mit Bridges hinbekommt, variiert von Distribution zu Distribution und ist nicht Teil dieser Anleitung. (Ich werde aber ganz unten meine eigene spezielle Konfiguration für Gentoo vorstellen.)
Des Weiteren werden die "dosfstools" zum Erstellen von VFAT-Dateisystemen benötigt sowie die Programme "fdisk" und "losetup" aus dem Paket "util-linux".
Auch benötigen wir einen speziellen Kernel. Leider können wir nicht den fli4l-Kernel verwenden, weil dieser einen Raspberry Pi voraussetzt, der ja nicht emuliert werden kann. Wir brauchen stattdessen einen Kernel, der eine "versatilepb"-Maschine erwartet, denn diese kann von QEMU emuliert werden. Diesen Kernel kann/muss man von [http://xecdesign.com/downloads/linux-qemu/kernel-qemu] herunterladen.
Schließlich brauchen wir natürlich einen aktuellen fli4l-Checkout, und zwar den SVN-Zweig 4.0/trunk ab Revision r38903. Den kann man sich wie folgt beschaffen:
$ svn checkout -r 38903 https://ssl.nettworks.org/svn/fli4l/branches/4.0/trunk
<ENTER>
Konfiguration
Man kann eine beliebige fli4l-Konfiguration wählen, welche aber den folgenden Bedingungen genügt:
- nur eine Netzwerkkarte (mehr geht leider nicht), d.h.
IP_NET_N='1'
- kein IPv6 (kann der oben erwähnte versatilepb-Kernel leider nicht)
- will man das Paket "hwsupp" nutzen (momentan hat es beim Raspberry Pi keine Funktion), muss man
HWSUPP_TYPE='rpi'
setzen OPT_E3
undOPT_VALGRIND
müssen beide aufno
gesetzt werden, des Weiteren braucht manPOWERMANAGEMENT='none'
undBEEP='no'
- keine Festplatten-Installation und Recover-Funktionatlität, weil SYSLINUX fehlt, deshalb
OPT_HDINSTALL='no'
undOPT_RECOVER='no'
- auch wenn der fli4l-Kernel nicht benutzt wird, weiß das "mkfli4l" ja nicht; da es weder "-virt"-Kernel noch "3.18.*"-Kernel für den R'Pi gibt, muss man
KERNEL_VERSION='3.19.6'
oderKERNEL_VERSION='3.19.6-nonfree'
verwenden
Erstellen des Installationsmediums
Zuerst konfiguriert man seine mkfli4l.txt
so, dass kein Remote-Update vorgenommen wird (REMOTEUPDATE='no'
). Dann lässt man wie üblich mkfli4l.sh
laufen und hat hinterher in config/build
die folgenden Dateien vorliegen:
rc.cfg
, die Konfigurationsdateikernel
, den fli4l-Kernelrootfs.img
, das RootFS-Archivopt.img
, das OPT-Archiv
Diese gilt es nun auf ein geeignetes Boot-Medium zu kopierern. Zuerst erstellen wir dies via dd
:
$ dd if=/dev/zero of=rpi-hd.img bs=1048576 count=64
<ENTER>64+0 Datensätze ein
64+0 Datensätze aus
67108864 Bytes (67 MB) kopiert, 0,93694 s, 71,6 MB/s
$
Dann müssen wir eine Partition anlegen. Dies kann man z.B. via fdisk
erledigen:
$ /sbin/fdisk rpi-hd.img
<ENTER>Willkommen bei fdisk (util-linux 2.25.2).
Änderungen werden vorerst nur im Speicher vorgenommen, bis Sie sich
entscheiden, sie zu schreiben.
Seien Sie vorsichtig, bevor Sie den Schreibbefehl anwenden.
Gerät enthält keine erkennbare Partitionstabelle.
Created a new DOS disklabel with disk identifier 0xfafe4f9c.
Befehl (m für Hilfe): n
<ENTER>Partitionstyp
p Primär (0 primär, 0 erweitert, 4 frei)
e Erweitert (Container für logische Partitionen)
Wählen (Vorgabe p):
<ENTER>Standardantwort p wird verwendet.
Partitionsnummer (1-4, Vorgabe 1):
<ENTER>Erster Sektor (2048-131071, Vorgabe 2048):
<ENTER>Letzter Sektor, +Sektoren oder +Größe{K,M,G,T,P} (2048-131071, Vorgabe 131071):
<ENTER>Eine neue Partition 1 des Typs »Linux« und der Größe 63 MiB wurde erstellt.
Befehl (m für Hilfe): t
<ENTER>Partition 1 ausgewählt
Hexadezimalcode (geben Sie L ein, um alle Codes aufzulisten): 6
<ENTER>WARNUNG: Wenn Sie eine DOS-6.x-Partition angelegt oder verändert haben, dann schauen Sie bitte in die cfdisk-Handbuchseite nach weiteren Informationen.
Partitionstyp von »Linux« nach »FAT16« geändert.
Befehl (m für Hilfe): a
<ENTER>Partition 1 ausgewählt
Die Bootfähig-Markierung auf Partition 1 ist nun aktiviert.
Befehl (m für Hilfe): w
<ENTER>Die Partitionstabelle wurde verändert.
Festplatten werden synchronisiert.
$
Nun erstellen wir auf unserem Rechner ein Gerät für diese Partition, damit wir sie einhängen können:
$ sudo losetup -f -P --show rpi-hd.img
Passwort: ......<ENTER>
/dev/loop0
Dank der Option "-P" ist die Partition unter /dev/loop0p1
verfügbar (oder allgemein unter /dev/loopXp1
, falls ein anderer Index als "null" von losetup
zurückgeliefert wird). Diese können wir nun einhängen, die Dateien darauf kopieren und wieder aushängen:
$ sudo mkdir /mnt/rpi
<ENTER>$ sudo mount /dev/loop0p1 /mnt/rpi
<ENTER>$ sudo cp -a config/build/{rc.cfg,kernel,rootfs.img,opt.img} /mnt/rpi/
<ENTER>$
sudo umount /mnt/rpi
<ENTER>
$
Jetzt entfernen wir noch das loop
-Gerät:
$
sudo losetup -d /dev/loop0
<ENTER>
$
Geschafft! Das Boot-Medium ist bereit.
Emulation
Nun müssen wir nur noch QEMU starten:
$ qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "console=ttyAMA0,115200 console=tty1 panic=1 load_ramdisk=1" \
<ENTER>
-initrd config/build/rootfs.img -hda rpi-hd.img -netdev bridge,id=net0,br=br0 -net nic,netdev=net0Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0x0
Linux version 3.10.26+ (shift@Shift-PC) (gcc version 4.7.3 (Gentoo 4.7.3-r1 p1.4, pie-0.5.5) ) #2 Fri Jan 17 22:13:59 EST 2014
CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387d
CPU: VIPT aliasing data cache, unknown instruction cache
Machine: ARM-Versatile PB
[...]
Fertig!
Screenshots
Anhang A: Gentoo-Netzwerk-Konfiguration
Die unter "Emulation" verwendete Netzwerkbrücke br0
wird wie folgt über die /etc/conf.d/net
konfiguriert:
config_br0="dhcp"
brctl_br0="setfd 0
sethello 10
stp off"
mac_br0="00:25:22:6c:68:f4"
bridge_br0="enp0s10"
Das Programm brctl
gibt Folgendes aus, während die fli4l-VM läuft:
$ /sbin/brctl show br0
bridge name bridge id STP enabled interfaces
br0 8000.0025226c68f4 no enp0s10
tap0