Emulacja wbudowanych systemów Linux za pomocą QEMU
Emulacja wbudowanych systemów Linux za pomocą QEMU
1. Wstęp
Tworzenie oprogramowania osadzonego opiera się na wbudowanych urządzeniach sprzętowych, takich jak płyty rozwojowe, urządzenia modułów zewnętrznych itp., ale jeśli debugowanie nie ma nic wspólnego z urządzeniami peryferyjnymi, tylko debugowanie jądra może być symulowane przy użyciu QEMU bez kupowania sprzętu.
Jest dostępny dla hostów Linux i Windows oraz emulowanych celów PowerPC, ARM, MIPS i SPARC. QEMU przyjmuje podejście polegające na zapewnieniu minimalnej warstwy translacji między procesorem hosta a procesorem docelowym. Emulator jest uruchamiany na procesorze hosta, a emulowany jest procesor docelowy.
Poniżej znajduje się szczegółowe wprowadzenie do procesu tworzenia środowiska programistycznego QEMU.
2. Środowisko
2.1 Używane środowisko
* Ubuntu-18.04.1
LUB:
* Komputer: Windows10
* Maszyna wirtualna: VirtualBox-5.18
* Wirtualny system operacyjny:Ubuntu-18.04.1
* Symulowana tablica rozwojowa: vexpres
2.2 Narzędzia używane podczas konfigurowania środowiska
* qemu-4.2.0
* linux-4.14.172 (Jądro Linuksa)
* u-boot-2017.05
* zajęta skrzynka-1.31.1
* ramię-linux-gnueabi-gcc
Umieść wszystkie powiązane pliki w /home/joe/qemu
3. Zainstaluj narzędzia do kompilacji krzyżowej
# Sudo apt install gcc-arm-linux-gnueabi
Sprawdź, czy instalacja się powiodła
$ arm-linux-gnueabi-gcc -v
Korzystanie z wbudowanych specyfikacji. COLLECT_GCC=arm-linux-gnueabi-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabi/7/lto-wrapper Cel: ramię-linux-gnueabi Skonfigurowany z: ../src/configure -v –with-pkgversion='Ubuntu/Linaro 7.5.0-3ubuntu1~18.04′–with-bugurl=file:///usr Model wątku: posix Wersja gcc 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) |
4. Skonfiguruj i skompiluj jądro Linux
4.1 Pobierz jądro Linuksa
Pobierz wymaganą wersję jądra ze strony www.kernel.org.
Tutaj pobieram stosunkowo najnowszą, długoterminowo wspieraną wersję jądra linux-4.4.157
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.157.tar.xz do katalogu /qemu
4.2 Rozpakuj jądro Linux
# tar xvJf linux-4.4.157.tar.xz
4.3 Kompilowanie jądra Linux
// Wprowadź katalog plików źródłowych jądra
# płyta CD Linux-4.4.157
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm vexpress_defconfig
make CROSS_COMPILE=arm-linux-gnueabi-ARCH=arm menuconfig
Jeśli uruchomienie menuconfig pokazuje, że brakuje pakietu ncurses, po prostu uruchom następujące polecenie, aby go zainstalować)
$ sudo apt-get zainstaluj libncurses5-dev
Wejdź do konfiguracji menu i dokonaj następujących ustawień
Kompiluj z cross toolchain
Po udanej kompilacji wygeneruj plik obrazu jądra w katalogu
arch/arm/boot, zImage i dtb można skopiować do osobnego folderu w celu wygodnego użycia
5. Zainstaluj narzędzia QEMU
5.1 Zainstaluj QEMU
* wget https://download.qemu.org/qemu-4.2.0.tar.xz
* tar xvJf qemu-4.2.0.tar.xz
* płyta CD qemu-4.2.0
5.2 Zainstaluj zależne pakiety przed konfiguracją QEMU
# apt zainstaluj zlib1g-dev
# apt install libglib2.0-0 libglib2.0-dev
# apt zainstaluj libsdl1.2-dev
# apt install libpixman-1-dev libfdt-dev
Aby zapobiec bałaganowi w plikach po kompilacji, utwórz katalog konstruktora jako pośrednią ścieżkę docelową do kompilacji.
Skonfiguruj, skompiluj i zainstaluj QEMU.
5.3 Skonfiguruj QEMU do obsługi wszystkich płyt w architekturze ramienia
# ../configure –target-list=arm-softmmu –audio-drv-list=
Jeśli brakuje pixmana, gdy pojawi się następujący monit,
użyj sudo apt-get install libpixman-1-dev, aby go zainstalować.
5.4 Zobacz wersję QEMU
5.5 Wyświetl tablice rozwojowe obsługiwane przez QEMU
5.6 Uruchom QEMU
# qemu-system-arm -M vexpress-a9 -m 512M -kernel ./zImage -dtb ./vexpress-v2p-ca9.dtb -nographic -append „console=ttyAMA0”
LUB:
$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”
Aby lepiej testować i uruchamiać qemu, możesz utworzyć skrypt startowy start.sh i nadać skryptowi uprawnienia do uruchamiania chmod +x start.sh
#! / bin / bash
ramię-systemu qemu \
-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/boot/dts/vexpress-v2p-ca9.dtb \
-nograficzny \
-dołącz „konsola=ttyAMA0”
6. Stwórz główny system plików
Użyj busybox do stworzenia prostego głównego systemu plików.
6.1 Pobierz narzędzie busybox
Pobierz busybox z https://busybox.net/downloads/
# wget https://busybox.net/downloads/busybox-1.31.1.tar.bz2
# tar xjvf busybox-1.31.1.tar.bz2
# cd busybox-1.31.1
# zrobić defconfig
# make CROSS_COMPILE=arm-linux-gnueabi-
# make install CROSS_COMPILE=arm-linux-gnueabi-
Wyświetlone zostaną następujące informacje, wskazujące, że instalacja się powiodła.
Po zakończeniu instalacji wygenerowany plik docelowy domyślnie znajduje się w katalogu ./_install.
6.2 Generowanie głównego systemu plików
6.2.1 skompiluj i zainstaluj busybox
#mkdir rootfs
# sudo cp -r _install/* rootfs/
6.2.2 Dodaj bibliotekę glibc, dodaj loader i bibliotekę dynamiczną w głównym systemie plików
# sudo cp -r _install/* rootfs/
# Sudo cp -p /usr/arm-linux-gnueabi/lib/* rootfs/lib/
6.2.3 Utwórz 4 urządzenia terminalowe tty (c oznacza urządzenie znakowe, 4 to główny numer urządzenia, a 1~4 to odpowiednio podrzędne numery urządzeń)
6.3 Utwórz obraz systemu plików na karcie SD
6.3.1 Wygeneruj pusty obraz karty SD
# dd if=/dev/zero of=rootfs.ext3 bs=1M liczba=32
6.3.2 Sformatuj kartę SD jako system plików exts
# mkfs.ext3 rootfs.ext3
6.3.3 Nagrywanie rootfów na kartę SD
# sudo mount -t ext3 rootfs.ext3 /mnt -o pętla
# sudo cp -rf rootfs/* /mnt/
# sudo umount /mnt
7. Zweryfikuj
7.1 Uruchom Qemu
Uruchom następujące polecenie, aby przetestować, sprawdź, czy skompilowane jądro może działać pomyślnie
# sudo qemu-system-arm -M vexpress-a9 -m 512M -kernel ~/qemu/zImage –dtb ~/qemu/vexpress-v2p-ca9.dtb -nographic -append „console=ttyAMA0”
Lub za pomocą skryptu:
W powyższym teście jądro zgłosi panikę, co sugeruje, że brakuje nam głównego systemu plików.
Powyższy problem wynika z narzędzia busybox generowanego w środowisku x86.
Użyliśmy make install podczas instalacji busyboxa, więc powinieneś użyć
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-install |
Narzędzie do kompilacji generuje narzędzie busybox używane przez platformę ramienia
# plik rootfs/bin/busybox
rootfs/bin/busybox: 32-bitowy plik wykonywalny ELF LSB, ARM, EABI5 wersja 1 (SYSV), łączony dynamicznie, interpreter /lib/ld-, dla GNU/Linux 3.2.0, BuildID[sha1]=cbcd33b8d6c946cb19408a5e8e714de554c87f52, striped
7.2 Zweryfikuj ponownie
Teraz Qemu uruchomiło jądro Linux i pomyślnie zamontowało system plików, a także może komunikować się z systemem za pomocą prostych funkcji za pośrednictwem terminala szeregowego. Problem polegający na tym, że nie można uruchomić /etc/init.d/rcS w procesie drukowania, wystarczy dodać plik /etc/init.d/rcS. Zawartość pliku może być szybkim stwierdzeniem.
7.3 Wyjście z QEMU
Dwa sposoby na wyjście z qemu
* W innym wejściu terminala: zabij wszystkie qemu-system-arm
* W danych wejściowych Qemu: Ctrl+A; x
QEMU: rozwiązany
8. Uruchom jądro Linuksa przez u-boot
System wbudowany zazwyczaj obejmuje: u-boot, kernel, rootfs i appfs. Zależność pozycyjna tych części na płytce rozwojowej ARM pokazano na poniższym rysunku
Program rozruchowy | Parametry rozruchu | Jądro | Korzenie | Aplikacje |
Rootfs może działać na płycie lub komputerze
8.1 Przygotuj U-boot
8.1.1 Pobierz u-boot
http://ftp.denx.de/pub/u-boot/, używamy: u-boot-2021.01.tar.bz2
# tar -jxvf u-boot-2018.09.tar.bz2
8.1.2 Skompiluj u-boot
# vim Plik Makefile
CROSS_COMPILE = ramię-linux-gnueabi-
# vim config.mk
ŁUK = ramię
# make vexpress_ca9x4_defconfig, błąd
Potrzebujesz: sudo apt zainstaluj bizon
sudo apt zainstaluj flex
wtedy: # make -j4 error
Potrzebujesz: eksportuj CROSS_COMPILE=arm-linux-gnueabi-
eksportuj ARCH=ramię
ponownie: # make vexpress_ca9x4_defconfig
# make -j4
8.1.3 Test, uruchom u-boot
$ sudo qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot-2021.01/u-boot –nograficzny
8.2 Kompilacja konfiguracji jądra
Użyj u-boot, aby uruchomić obraz jądra:
Musisz skompilować jądro do formatu uImage,
Musisz określić adres ładowania uImage w pamięci
Określ podczas kompilacji jądra: make LOADADDR=? uObraz -j4
# cd /home/joe/qemu/linux-4.4.157
# make LOADADDR=0x60003000 uImage -j4
Po zakończeniu kompilacji u-boot, plik mkimage zostanie wygenerowany w folderze narzędzi, skopiuj ten plik do folderu bin w katalogu kompilatora krzyżowego.
$cd qemu/linux-4.4.157
błąd:
$ sudo apt zainstaluj narzędzia u-boot
Pobierz uImage
9. Ustawienia funkcji sieciowych QEMU
Gdy maszyna wirtualna Qemu uruchamia się przy u-boot, uImage musi zostać załadowany do pamięci, a uImage można pobrać na określony adres w pamięci przez serwer TFTP.
9.1 Sprawdź, czy jądro hosta obsługuje moduł tun/tap
// Zainstaluj dwa narzędzia, od których zależy sieć zmostkowana
# Sudo apt install uml-utilities Bridge-utils
Utwórz plik urządzenia tun: /dev/net/tun (zwykle tworzony automatycznie)
Zmodyfikuj /etc/network/interfaces (skonfiguruj sieć, uruchom ponownie, aby odniosło skutek)
# sudo vim /etc/sieć/interfejsy
auto loiface lo inet loopbackauto enp0s3 // nazwa wirtualnej karty sieciowejauto br0iface br0 inet dhcpbridge_ports enp0s3 |
NIGDY nie uruchamia się ponownie
# restart
Następnie sprawdź środowisko sieciowe Qemu
Port sieci wirtualnej br0 to port sieciowy do komunikacji między maszyną wirtualną Qemu a hostem Linux.
10. Zainstaluj serwer TFTP
Utwórz serwer TFTP, aby pobrać uImage do pamięci podczas uruchamiania uImage dla płyty rozwojowej symulacji Qemu
10.1 Zainstaluj narzędzie tftp
$ apt-get install tftp-hpa tftpd-hpa xinetd
10.2 Zmodyfikuj plik konfiguracyjny i ustaw katalog serwera TFTP
# Sudo vim /etc/default/tftpd-hpa
...... TFTP_DIRECTORY="/home/joe/tftpboot" ...... |
10.3 Utwórz katalog tftp na hoście Linux
# mkdir /home/joe/tftpboot
# chmod 777 /home/joe/tftpboot
10.4 Uruchom ponownie usługę tftp
# restart sudo /etc/init.d/tftpd-hpa
10.5 Ustaw parametry startowe jądra w u-boot
skopiuj uImage i cexpress-v2p-ca9.dtb do tftpboot
Uruchom Qemu, aby zweryfikować
$ 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. wew3
Teraz katalog rootfs jest prostym systemem plików root, który można przekształcić w plik lustrzany, a plik lustrzany można nagrać na płytę rozwojową lub jądro Linuksa można uruchomić przez u-boot w Qemu i zamontować na plik lustrzany. Można go również ustawić na uruchamianie za pośrednictwem sieciowego systemu plików NFS.
11. Zamontuj system plików NFS
11.1 Zainstaluj i skonfiguruj usługę NFS
NIGDY nie instaluj
$ sudo apt zainstaluj serwer jądra nfs
11.1.2 Konfiguracja
$ Sudo mkdir /home/joe/qemu/rootfs
$ sudo chown none:nogroup /home/joe/qemu/rootfs
$ sudo chmod 777 /home/joe/qemu/rootfs
$ sudo nano /etc/eksport
Dodaj: /home/joe/qemu/rootfs *(rw,sync,no_root_squash)
Zrestartuj serwer nfs:
$ sudo /etc/init.d/nfs-kernel-server restart
Lub: $systemctl restart nfs-kernel-server
Sprawdź, czy został utworzony katalog współdzielony NFS
$ sudo showmount –e
Podczas korzystania z sieciowego systemu plików NFS host systemu Linux musi zamknąć zaporę systemową, w przeciwnym razie podczas działania systemu wystąpią nieprawidłowości.
Wnioski
Mam nadzieję, że dzięki temu blogowi dowiesz się więcej o QEMU. Wszystkie przedstawione powyżej techniki zostały użyte w różnych zgłoszeniach do naszego programu. Nie ma jednego, stałego sposobu emulowania z QEMU. Poznaj różne techniki i zobacz, co działa dla Ciebie. Zapoznaj się z tą wiedzą, a zdziwisz się, jak może Ci pomóc w nieoczekiwany sposób.