Sbc qemu emulation
Introduction
Lorsque l'on a pas de SBC physique on peut se tourner vers l'émulation pour faire des tests ! Attention cependant, les performances seront médiocres comme souvent avec l'émulation.
Nous allons utiliser l'émulateur Qemu pour émuler une architecture ARM et pouvoir exécuter une image de PI.
SBC et SoC
Les composants qui forment chacun des SBC va influer sur les performances, capacité, etc... et sont généralement rassemblés sous le nom de SoC. Le Raspberry PI utilise un SoC Broadcom BCM28XX alors que les autres SBC utilise un SoC AllWinner (H2, H3, A10, A20, etc...).
Le SoC peut être vu comme la compression de la carte mère, du CPU, de la RAM et du GPU. Le SBC et l'ajout, autour du SoC, des ports d'extension (USB, Ethernet, SD, etc...)
N'hésitez pas à lire le cours sur le matériel pour des explications plus poussées !
Le Raspberry... et les autres
Le Raspberry PI (et donc le SoC Broadcom BCM28XX) possède en plus du CPU ARM un GPU VideoCore alors que les SoC AllWinner possède un GPU Mali400 et jusque là pas de grosses différences sauf dans la phase de démarrage...
Le Raspberry PI, à l'inverse des autres SBC, n'amorce pas sa phase de démarre pas le biais de son CPU mais de son GPU !
Ci-dessous sont détaillés les phases de démarrage des différents SBC
Raspberry | Les autres |
---|---|
Après le démarrage du système d'exploitation, le code du GPU n'est pas déchargé de la RAM. En effet, start.elf n'est pas juste un firmware pour le GPU mais un système d'exploitation propriétaire appelé VideoCore OS (VCOS). Lorsque Linux nécessite un élément du GPU (caméra, 3D, etc...) il communique avec VCOS au travers du système de mail. |
On peut observer le répertoire boot à partir d'une image et pour cela il faut:
|
Pour émuler un Raspberry PI l'émulateur va devoir jouer le rôle du CPU ARM et du GPU alors que dans les autres cas, seulement le CPU sera nécessaire !
Utilisation de Qemu
Tout d'abord assurez-vous d'avoir téléchargé l'émulateur pour votre OS et modifié votre variable PATH pour y ajouter le répertoire d'installation de Qemu. Une fois installé, on peut mesurer le nombre d'architecture supportée par Qemu !
Ceux qui vont nous intéresser sont :
- qemu-system-arm pour les processeur ARM jusqu'à la V7 (32bits)
- qemu-system-aarch64 pour les processeur ARM V8+ (64bits)
Qemu s'utilise en ligne de commande avec certains paramètres dont voici les principaux:
- -M: pour spécifier le type de machine émulée;
- -m : pour spécifier la quantité de RAM
- -cpu : pour spécifier le type de CPU
- -nic : pour paramétrer la carte réseau
- -drive : pour spécifier un disque système
- -dtb : pour préciser l'arbre matériel (DeviceTree Binary)
- -kernel : pour préciser le noyau utilisé
- -initrd : pour spécifier le schéma de la RAM (initram FS)
Démarche pour émuler
Les SoC AllWinner
Imaginons que nous voulions émuler un SoC AllWinner H2+. |
|||||||||||||||||||||||
Cette carte utilise un SoC AllWinner H2+ et d'après la documentation de AllWinner le CPU est un ARM Cortex-A7 (32 bits): |
|||||||||||||||||||||||
Il ne nous reste plus qu'a trouver un SBC avec le même jeu d'instruction (ARMv7) équivalent dans Qemu: |
# qemu-system-arm -M help Supported machines are: akita Sharp SL-C1000 (Akita) PDA (PXA270) ast2500-evb Aspeed AST2500 EVB (ARM1176) ast2600-evb Aspeed AST2600 EVB (Cortex A7) bast Simtec Electronics BAST (S3C2410A, ARM920T) borzoi Sharp SL-C3100 (Borzoi) PDA (PXA270) canon-a1100 Canon PowerShot A1100 IS cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310) collie Sharp SL-5500 (Collie) PDA (SA-1110) connex Gumstix Connex (PXA255) cubieboard cubietech cubieboard (Cortex-A9) emcraft-sf2 SmartFusion2 SOM kit from Emcraft (M2S010) highbank Calxeda Highbank (ECX-1000) imx25-pdk ARM i.MX25 PDK board (ARM926) integratorcp ARM Integrator/CP (ARM926EJ-S) kzm ARM KZM Emulation Baseboard (ARM1136) lm3s6965evb Stellaris LM3S6965EVB ... | ||||||||||||||||||||||
On remarque que que des SBCs utilisent un CPU Cortex-A (cubieboard, ast2600-evb, ...) de la même famille que le Cortex-A7 et son donc 100% compatible (The ARM Cortex-A7 MPCore processor is fully compatible with other Cortex-A family of processors). Il ne reste plus qu'a télécharger l'image d'Armbian sur le site d'OrangePi et de la décompresser pour regarder le répertoire boot et notamment la partie dtd: |
|||||||||||||||||||||||
On remarque qu'une dtd existe pour le SBC cubieboard, c'est donc celui-ci que nous allons utiliser avec les fichiers vmlinuz et initrd qui vont avec ! Dans un répertoire décompressez les fichiers initrd, vmlinuz et dtd correspondant (grâce à 7zip si vous êtes sous Windows) |
|||||||||||||||||||||||
Vous pouvez créez un script bat avec le contenu suivant: |
qemu-system-arm.exe ^ -M cubieboard -m 512 -cpu cortex-a7 ^ -dtb .\sun4i-a10-cubieboard.dtb ^ -kernel .\vmlinuz-5.4.20-sunxi ^ -initrd .\initrd.img-5.4.20-sunxi ^ -drive file=.\Armbian_20.02.1_Orangepizero_buster_current_5.4.20.img,format=raw,if=none,id=d1 ^ -device ide-hd,drive=d1 ^ -append "nosmp earlyprintk loglevel=8 earlycon=uart8250,mmio32,0x1c28000,115200n8 console=ttyS0 root=/dev/sda1" ^ -nographic -serial stdio -monitor none ^ -nic user,model=allwinner-emac,hostfwd=tcp::2222-:22 | ||||||||||||||||||||||
Reprenons dans l'ordre: |
| ||||||||||||||||||||||
Cela permet, après le temps à l'émulateur de démarrer le système, de pouvoir se logger. |
Le Raspberry Pi
Pour le Raspberry Pi les choses ne sont pas aussi simple, comme le code du SoC Broadcom BCM28XX est propriétaire il faut donc trouver un équivalent libre qui va émuler le même comportement que le VideoCore OS. Heureusement que le modèle raspi3 sur Qemu fait cela !
Il ne reste plus qu'à trouver un kernel compatible avec cet émulation et c'est justement ce que le projet suivant propose: qemu-rpi-kernel
Une fois l'image du système d'exploitation téléchargée (ici Debian Buster) on peut créer un répertoire avec les fichiers suivants :
|
|
Enfin, on peut créer le fichier bat suivant: qemu-system-aarch64 ^ -M raspi3 ^ -m 1024 ^ -dtb .\versatile-pb-buster.dtb ^ -kernel .\kernel-qemu-4.19.50-buster ^ -drive file=.\2020-02-13-raspbian-buster-lite.img,format=raw ^ -append "rw root=/dev/sda2" ^ -net user,hostfwd=tcp::2222-:22 ^ -no-reboot pause |