Steuerplatine

Emulation von Embedded Linux-Systemen mit QEMU

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.

Kontakt