Emulation von Embedded Linux-Systemen mit QEMU
1. Einleitung
Die Entwicklung eingebetteter Software beruht auf eingebetteten Hardwaregeräten wie Entwicklungsboards, externen Modulgeräten usw., aber wenn die Debugging-Arbeit nichts mit Peripheriegeräten zu tun hat, kann nur das Kernel-Debugging mit QEMU simuliert werden, ohne Hardware zu kaufen.
Es ist für Linux- und Windows-Hosts und emulierte PowerPC-, ARM-, MIPS- und SPARC-Ziele verfügbar. QEMU verfolgt den Ansatz, eine minimale Übersetzungsschicht zwischen dem Host und dem Zielprozessor bereitzustellen. Der Host-Prozessor ist derjenige, auf dem der Emulator ausgeführt wird, und der Zielprozessor wird emuliert.
Im Folgenden finden Sie eine detaillierte Einführung in den Prozess zum Einrichten der QEMU-Entwicklungsumgebung.
2. Umgebung
2.1 Verwendete Umgebung
* Ubuntu-18.04.1
ODER:
* PC: Windows10
* Virtuelle Maschine: VirtualBox-5.18
* Virtuelles Betriebssystem: Ubuntu-18.04.1
* Simuliertes Entwicklungsboard: vexpres
2.2 Werkzeuge, die beim Einrichten der Umgebung verwendet werden
*qemu-4.2.0
* linux-4.14.172 (Linux-Kernel)
* u-boot-2017.05
* Busybox-1.31.1
* Arm-Linux-GNUEABI-GCC
Legen Sie alle zugehörigen Dateien in /home/joe/qemu . ab
3. Installieren Sie Cross-Compilation-Tools
# sudo apt install gcc-arm-linux-gnueabi
Überprüfen Sie, ob die Installation erfolgreich war
$ arm-linux-gnueabi-gcc -v
Verwenden von eingebauten Inspektionen. COLLECT_GCC=arm-linux-gnueabi-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabi/7/lto-wrapper Ziel: arm-linux-gnueabi Konfiguriert mit: ../src/configure -v –with-pkgversion='Ubuntu/Linaro 7.5.0-3ubuntu1~18.04′–with-bugurl=file:///usr Gewindemodell: Posix gcc-Version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) |
4. Konfigurieren und kompilieren Sie den Linux-Kernel
4.1 Linux-Kernel herunterladen
Laden Sie die erforderliche Kernel-Version von www.kernel.org herunter.
Hier lade ich die relativ neueste langfristig unterstützte Kernel-Version linux-4.4.157 herunter
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.157.tar.xz zum /qemu-Verzeichnis
4.2 Entpacken des Linux-Kernels
# tar xvjf linux-4.4.157.tar.xz
4.3 Linux-Kernel kompilieren
// Geben Sie das Kernel-Quelldateiverzeichnis ein
# cd linux-4.4.157
make CROSS_COMPILE=arm-linux-gnueabi-ARCH=arm vexpress_defconfig
make CROSS_COMPILE=arm-linux-gnueabi-ARCH=arm menuconfig
Wenn das Ausführen von menuconfig anzeigt, dass das ncurses-Paket fehlt, führen Sie einfach den folgenden Befehl aus, um es zu installieren)
$ sudo apt-get install libncurses5-dev
Rufen Sie die Menükonfiguration auf und nehmen Sie die folgenden Einstellungen vor
Kompilieren mit Cross-Toolchain
Generieren Sie nach erfolgreicher Kompilierung eine Kernel-Image-Datei unter dem Verzeichnis
arch/arm/boot, zImage und dtb können zur bequemen Verwendung in einen separaten Ordner kopiert werden
5. QEMU-Tools installieren
5.1 QEMU . installieren
* wget https://download.qemu.org/qemu-4.2.0.tar.xz.
* tar xvJf qemu-4.2.0.tar.xz
* CD-Qemu-4.2.0
5.2 Installieren Sie abhängige Pakete, bevor Sie QEMU konfigurieren
# apt installiere zlib1g-dev
# apt installiere libglib2.0-0 libglib2.0-dev
# apt installiere libsdl1.2-dev
# apt installiere libpixman-1-dev libfdt-dev
Um zu verhindern, dass die Dateien nach der Kompilierung unordentlich werden, erstellen Sie das Builder-Verzeichnis als Zwischenzielpfad für die Kompilierung.
QEMU konfigurieren, kompilieren und installieren.
5.3 Konfigurieren Sie QEMU, um alle Boards unter der Arm-Architektur zu unterstützen
#./configure-target-list = arm-soldmmu -audio-drv-list =
Wenn pixman fehlt, wenn die folgende Eingabeaufforderung erscheint,
Verwenden Sie sudo apt-get install libpixman-1-dev, um es zu installieren.
5.4 QEMU-Version anzeigen
5.5 Von QEMU unterstützte Entwicklungsboards anzeigen
5.6 QEMU . ausführen
# qemu-system-arm -M vexpress-a9 -m 512M -kernel ./zImage -dtb ./vexpress-v2p-ca9.dtb -nographic -append „console=ttyAMA0“
ODER:
$pwd
/home/joe/qemu
# qemu-system-arm -M vexpress-a9 -m 512M -kernel linux-.4.157/arch/arm/boot/zImage -dtb linux-4.4.157/arch/arm/boot/dts/vexpress-v2p-ca9. dtb -nographic -append „console=ttyAMA0“
Um qemu besser testen und starten zu können, können Sie das Startskript start.sh erstellen und dem Skript die Berechtigung erteilen, chmod +x start.sh auszuführen
#! / Bin / bash
qemu-system-arm \
-M vexpress-a9 \
-m 512M \
-kernel /home/joe/jemu/linux-4.4.157/arch/arm/boot/zImage \
-dtb /home/joe/jemu/linux-4.4.157/arch/arm/woot/dts/vexpress-v2p-ca9.dtb \
-nografisch \
- "console=ttyAMA0" anhängen
6. Erstellen Sie ein Root-Dateisystem
Verwenden Sie busybox, um ein einfaches Root-Dateisystem zu erstellen.
6.1 Busybox-Tool herunterladen
Laden Sie busybox von https://busybox.net/downloads/ herunter
# wget https://busybox.net/downloads/busybox-1.31.1.tar.bz2
# tar xjvf busybox-1.31.1.tar.bz2
# cd busybox-1.31.1
# defconfig erstellen
# make CROSS_COMPILE=arm-linux-gnueabi-
# Installieren Sie cross_compile = arm-linux-gnuebi-
Die folgenden Informationen werden angezeigt, um anzuzeigen, dass die Installation erfolgreich war.
Nach Abschluss der Installation wird standardmäßig das Verzeichnis ./_install für die generierte Zieldatei verwendet.
6.2 Root-Dateisystem generieren
6.2.1 Busybox kompilieren und installieren
# mkdir rootfs
# sudo cp -r _install/* rootfs/
6.2.2 Glibc-Bibliothek hinzufügen, Loader und dynamische Bibliothek im Root-Dateisystem hinzufügen
# sudo cp -r _install/* rootfs/
# sudo cp -p / usr / arm-linux-gnueabi / lib / * rootfs / lib /
6.2.3 Erstellen Sie 4 tty-Endgeräte (c steht für Zeichengerät, 4 ist die Hauptgerätenummer und 1~4 sind die Nebengerätenummern)
6.3 SD-Karten-Dateisystem-Image erstellen
6.3.1 Ein leeres SD-Karten-Image erstellen
# DD if = / dev / null von = rootfs.ext3 BS = 1M Anzahl = 32
6.3.2 SD-Karte als exts-Dateisystem formatieren
# mkfs.ext3 rootfs.ext3
6.3.3 Rootfs auf SD-Karte brennen
# sudo mount -t ext3 rootfs.ext3 /mnt -o Schleife
# sudo cp -rf rootfs/* /mnt/
# sudo umount /mnt
7. Überprüfen Sie
7.1 Qemu . starten
Führen Sie den folgenden Befehl aus, um zu testen, ob der kompilierte Kernel erfolgreich ausgeführt werden kann
# sudo qemu-system-arm -M vexpress-a9 -m 512M -kernel ~/qemu/zImage –dtb ~/qemu/vexpress-v2p-ca9.dtb -nographic -append „console=ttyAMA0“
Oder mit Skript:
Im obigen Test meldet der Kernel Panik, was darauf hindeutet, dass uns das Root-Dateisystem fehlt.
Das obige Problem ist auf das Busybox-Tool zurückzuführen, das in der x86-Umgebung generiert wurde.
Wir haben make install bei der Installation von busybox verwendet, also sollten Sie verwenden
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-install |
Das Kompilierungstool generiert das Busybox-Tool, das von der Arm-Plattform verwendet wird
# Datei rootfs/bin/busybox
rootfs/bin/busybox: ELF 32-bit LSB Executable, ARM, EABI5 Version 1 (SYSV), dynamisch gelinkt, Interpreter /lib/ld-, für GNU/Linux 3.2.0, BuildID[sha1]=cbcd33b8d6c946cb19408a5e8e714de554c87f52, stripped
7.2 Erneut verifizieren
Nun hat Qemu den Linux-Kernel gestartet und das Dateisystem erfolgreich gemountet und kann mit einfachen Funktionen über das serielle Terminal mit dem System interagieren. Das Problem, dass /etc/init.d/rcS im Druckprozess nicht ausgeführt werden kann, Sie müssen nur die Datei /etc/init.d/rcS hinzufügen. Der Inhalt der Datei kann eine Prompt-Anweisung sein.
7.3 QEMU . beenden
Zwei Möglichkeiten, qemu . zu beenden
* In einer anderen Terminaleingabe: kill all qemu-system-arm
* Bei Qemu-Eingabe: Strg+A; x
QEMU: Beendet
8. Starten Sie den Linux-Kernel über u-boot
Eingebettete Systeme umfassen normalerweise: u-boot, kernel, rootfs und appfs. Die Positionsbeziehung dieser Teile auf der ARM-Entwicklungsplatine, wie in der Abbildung unten gezeigt
Bootloader | BootParameter | Kernel | rootfs | Apps |
Rootfs können in Board oder PC ausgeführt werden
8.1 U-Boot vorbereiten
8.1.1 u-boot herunterladen
http://ftp.denx.de/pub/u-boot/, wir verwenden: u-boot-2021.01.tar.bz2
# tar -jxvf u-boot-2018.09.tar.bz2
8.1.2 U-Boot kompilieren
# vim-Makefile
CROSS_COMPILE = arm-linux-gnueabi-
# vim config.mk
ARCH = Arm
# make vexpress_ca9x4_defconfig, Fehler
Benötigen: sudo apt install bison
Sudo apt install flex
dann: # make -j4 error
Benötigen: export CROSS_COMPILE=arm-linux-gnueabi-
export ARCH=arm
nochmal: # make vexpress_ca9x4_defconfig
# make -j4
8.1.3 Test, u-boot starten
$ sudo qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot-2021.01/u-boot –nographic
8.2 Zusammenstellung der Kernel-Konfiguration
Verwenden Sie u-boot, um das Kernel-Image zu booten:
Muss den Kernel in das uImage-Format kompilieren,
Muss die Ladeadresse von uImage im Speicher angeben
Geben Sie beim Kompilieren des Kernels Folgendes an: make LOADADDR=? uImage -j4
# cd /home/joe/qemu/linux-4.4.157
# make LOADADDR=0x60003000 uImage -j4
Nachdem die U-Boot-Kompilierung abgeschlossen ist, wird eine mkimage-Datei im Tool-Ordner erstellt, kopieren Sie diese Datei in den bin-Ordner unter dem Cross-Compiler-Verzeichnis.
$ cd qemu/linux-4.4.157
Fehler:
$ sudo apt installiere u-boot-tools
Holen Sie sich uImage
9. QEMU-Netzwerkfunktionseinstellungen
Wenn die virtuelle Qemu-Maschine beim u-Boot startet, muss uImage in den Speicher geladen werden und uImage kann über den TFTP-Server an die angegebene Adresse im Speicher heruntergeladen werden.
9.1 Prüfen Sie, ob der Host-Kernel das tun/tap-Modul unterstützt
// Installieren Sie die beiden Tools, von denen das Bridged-Netzwerk abhängt
# sudo apt installieren UML-Utilities Bridge-Utils
Tun-Gerätedatei erstellen: /dev/net/tun (normalerweise automatisch erstellt)
Ändern Sie /etc/network/interfaces (konfigurieren Sie das Netzwerk, starten Sie es neu, damit es wirksam wird)
# sudo vim / etc / network / interfaces
auto loiface lo inet loopbackauto enp0s3 // Name der virtuellen Netzwerkkarteauto br0iface br0 inet dhcpbridge_ports enp0s3 |
NIEMALS neu starten
# Neustart
Dann überprüfen Sie die Netzwerkumgebung von Qemu
Der virtuelle Netzwerkport br0 ist der Netzwerkport für die Kommunikation zwischen der virtuellen Qemu-Maschine und dem Linux-Host.
10. TFTP-Server installieren
Erstellen Sie einen TFTP-Server, um uImage in den Speicher herunterzuladen, wenn Sie uImage für das Qemu-Simulationsentwicklungsboard starten
10.1 tftp-Tool installieren
$ APT-GET INSTALL TFTP-HPA TFTPD-HPA XINETD
10.2 Ändern Sie die Konfigurationsdatei und legen Sie das TFTP-Serververzeichnis fest
# sudo vim /etc/default/tftpd-hpa
...... TFTP_DIRECTORY=“/home/joe/tftpboot“ ...... |
10.3 Erstellen Sie ein tftp-Verzeichnis auf dem Linux-Host
# mkdir /home/joe/tftpboot
# chmod 777 /home/joe/tftpboot
10.4 Starten Sie den tftp-Dienst neu
# sudo /etc/init.d/tftpd-hpa Neustart
10.5 Kernel-Startparameter in u-boot einstellen
uImage und cexpress-v2p-ca9.dtb nach tftpboot kopieren
Qemu starten, um zu überprüfen
$ sudo qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot-2021.01/u-boot –nographic -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 -sd rootfs. ext3
Nun ist das rootfs-Verzeichnis ein einfaches Root-Dateisystem, das in eine Spiegeldatei umgewandelt werden kann, und die Spiegeldatei kann auf das Entwicklungsboard gebrannt werden, oder der Linux-Kernel kann per U-Boot in Qemu gestartet und auf dem gemountet werden Spiegeldatei. Es kann auch so eingestellt werden, dass es über das NFS-Netzwerkdateisystem bootet.
11. NFS-Dateisystem mounten
11.1 NFS-Dienst installieren und konfigurieren
11.1.1 installieren
$ sudo apt installieren nfs-kernel-server
11.1.2 Konfiguration
$ sudo mkdir /home/joe/qemu/rootfs
$ sudo chown niemand:nogroup /home/joe/qemu/rootfs
$ sudo chmod 777 / home / joe / qemu / rootfs
$ sudo nano /etc/exports
Hinzufügen: /home/joe/qemu/rootfs *(rw,sync,no_root_squash)
nfs-Server neu starten:
$ sudo /etc/init.d/nfs-kernel-server restart
Oder: $systemctl restart nfs-kernel-server
Überprüfen Sie, ob das freigegebene NFS-Verzeichnis erstellt wurde
$ sudo showmount -e
Bei Verwendung des NFS-Netzwerkdateisystems muss der Linux-Host die System-Firewall schließen, da sonst bei laufendem System Anomalien auftreten.
Zusammenfassung
Hoffentlich wissen Sie mit Hilfe dieses Blogs mehr über QEMU. Alle oben demonstrierten Techniken wurden in verschiedenen Einreichungen für unser Programm verwendet. Es gibt keinen einzigen, festen Weg, um mit QEMU zu emulieren. Entdecken Sie verschiedene Techniken und sehen Sie, was für Sie funktioniert. Machen Sie sich mit dem Wissen vertraut und Sie werden überrascht sein, wie es Ihnen auf unerwartete Weise helfen kann.