Émulation Debian Raspberry Pi OS 64 bits sur un hôte amd64 - Qemu - carte virt

Création : Hôte : Debian Buster / 10.5, invités : images arm64 pour RaspBerry 3 et RaspBerry 4 : Debian RaspBerry unofficial Buster 10.5

L'objectif est d'émuler sur un PC amd64, les OS Debian RaspBerry Pi 3 & 4 64 bits

La méthode utilisée est reprise de https://github.com/wimvanderbauwhede/limited-systems/wiki/Debian-%22buster%22-for-Raspberry-Pi-3-on-QEMU

  • Elle utilise la plateforme qemu carte Virt (Virt 5.0) en version aarm64 (64 bits)

  • Elle fait appel pour l'amorçage aux noyaux et DTBs (Device Tree Blob) extraits des images

Sommaire

  • Émulation Debian RaspBerry Pi OS 64 bits sur un hôte amd64 - Qemu - carte virt
  • Carte virt
  • Installation
  • Téléchargement des images
  • Image RaspBerry Pi 3
    • Extraction du noyau
    • Lancement de l'émulation
    • Utilisation
    • Informations sur le système émulé
  • Image RaspBerry Pi 4
    • Extraction du noyau
    • Lancement de l'émulation
    • Informations sur le système installé

Carte virt

Extraits de la documentation de la carte virt ; https://qemu.readthedocs.io/en/latest/system/arm/virt.html
  • If you don’t care about reproducing the idiosyncrasies of a particular bit of hardware, such as small amount of RAM, no PCI or other hard disk, etc., and just want to run Linux, the best option is to use the virt board. This is a platform which doesn’t correspond to any real hardware and is designed for use in virtual machines. ...
  • Supported guest CPU types:
    • cortex-a7 (32-bit)
    • cortex-a15 (32-bit; the default)
    • cortex-a53 (64-bit)
    • cortex-a57 (64-bit)
    • cortex-a72 (64-bit)
    • host (with KVM only)
    • max (same as host for KVM; best possible emulation with TCG)

Note that the default is cortex-a15, so for an AArch64 guest you must specify a CPU type.

  • Graphics output is available, but unlike the x86 PC machine types there is no default display device enabled: you should select one from the Display devices section of “-device help”. The recommended option is virtio-gpu-pci; this is the only one which will work correctly with KVM. You may also need to ensure your guest kernel is configured with support for this; see below.

Installation

  • On suppose qemu installé pour l'architecture arm 64 bits (aarch64)
$ qemu-system-aarch64 --version
QEMU emulator version 5.0.0 (Debian 1:5.0-14~bpo10+1)
Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers
  • Vérifier la présence du modèle virt et noter la version, ici virt-5.0
$ qemu-system-aarch64 -machine help |grep virt
....
virt QEMU 5.0 ARM Virtual Machine (alias of virt-5.0)
virt-5.0 QEMU 5.0 ARM Virtual Machin

Téléchargement des images

  • Télécharger Debian Buster Raspberry Pi3 et Pi4 depuis https://raspi.debian.net/
$ wget https://raspi.debian.net/verified/20200831_raspi_3.img.{xz,sha256.asc}

$ wget https://raspi.debian.net/verified/20200909_raspi_4.img.{xz,sha256.asc}
  • Les images sont mises à disposition par Debian Gunnar Wolf / gwolf, mainteneur Debian. Rechercher l'empreinte de sa clé à partir https://nm.debian.org/public/people/ puis https://nm.debian.org/person/gwolf/
$ gpg --keyserver keyring.debian.org --recv-keys 4D14050653A402D73687049D2404C9546E145360
  • Vérifier la signature des checksums et la checksum des fichiers images compressés
$ gpg --verify 20200909_raspi_3.xz.sha256.asc
$ sha256sum -c 20200831_raspi_3.xz.sha256.asc

$ gpg --verify 20200909_raspi_4.xz.sha256.asc
$ sha256sum -c 20200909_raspi_4.xz.sha256.asc
  • Décompresser les images
$ unxz 20200831_raspi_3.img.xz
$ unxz 20200909_raspi_4.img.xz

Image RaspBerry Pi 3

Extraction du noyau

  • Établir les boucles de périphériques associées aux partitions de l'image et monter la partition racine (partition 2) en /mnt et la partition de boot (partition 1) en /mnt/boot/firmware (pour cette opération, les points de montage sont indifférents)
$ sudo losetup -P /dev/loop93 20200831_raspi_3.img
$ sudo mount /dev/loop93p2 /mnt
$ suod mount /dev/loop93p1 /mnt/boot/firmare
  • Recopier le noyau et la ligne de commande
$ cp /mnt/boot/initrd* /mnt/boot/vmlinuz ./
$ cp /mnt/boot/firmware/cmline.txt ./
  • Démonter les partitions et boucles
$ sudo umount /mnt/boot/firmware /mnt
$ sudo losetup -d /dev/loop93
  • Récapitulatif du contenu du répertoire courant
$ ls -l
total 1130696
-rw-r--r-- 1 philippe philippe 1572864000 oct. 5 16:16 20200831_raspi_3.img
-rwxr-xr-x 1 philippe philippe 123 oct. 5 16:15 cmdline.txt
-rw-r--r-- 1 philippe philippe 24839400 oct. 5 16:12 initrd.img-4.19.0-10-arm64
-rw-r--r-- 1 philippe philippe 18759536 oct. 5 16:12 vmlinuz-4.19.0-10-arm64

$ cat cmdline.txt
console=tty0 console=ttyS1,115200 root=LABEL=RASPIROOT rw elevator=deadline fsck.repair=yes net.ifnames=0 cma=64M rootwait
  • Notes :
    • la ligne de commande du système a été extraite pour information seulement et ne sera pas utilisée dans l'émulation
    • il y a une erreur dans la ligne de commande du système console=ttyS1 doit être remplacé par console=ttyA1

Lancement de l'émulation

  • La carte Raspberry Pi 3 est équipée d'un processeur Arm Cortex A53 et de 1 GB de RAM. Ces informations sont fournies dans les options -cpu et -m de la commande qemu. La commande est passée sous forme de script pour raison de simplicité
#!/usr/bin/env bash

RASPI=20200831_raspi_3.img VMLINUZ=vmlinuz-4.19.0-10-arm64 INITRD=initrd.img-4.19.0-10-arm64
qemu-system-aarch64 \ -kernel $PWD/$VMLINUZ \ -initrd $PWD/$INITRD \ -m 1024 -M virt \ -cpu cortex-a53 \ -serial stdio \ -append "rw root=/dev/vda2 console=ttyAMA0 loglevel=8 rootwait fsck.repair=yes memtest=1" \ -drive file=$RASPI,format=raw,if=sd,id=hd-root \ -device virtio-blk-device,drive=hd-root \ -netdev user,id=net0,hostfwd=tcp::5022-:22 \ -device virtio-net-device,netdev=net0 \ -no-reboot

exit

Utilisation

  • Lancer le script, deux consoles sont disponibles
    • Dans la fenêtre Qemu, la console de gestion de qemu (qemu)
    • Les entrées sortie du système sont redirigés vers le terminal d'où a été lancé l'émulation par l'option -serial stdio,

  • A l'invite de login, utiliser "root", sans mot de passe
  • Mettre à jour le nom d'hôte pour supprimer un message d'erreur récurrent

# echo rpi >/etc/hostname
# echo "127.0.1.1 rpi">>/etc/hosts
# hostname -F /etc/hosname
  • Se déconnecter, puis se reconnecter
# exit
#
  • Configurer le clavier, les locales, etc....
# export LC_ALL=C

# dpkg-reconfigure -f readline debconf
# apt install console_setup locales keyboard-configuration
.....
  • Une interface SSH a été mise en place par les options
  -netdev user,id=net0,hostfwd=tcp::5022-:22 \
  -device virtio-net-device,netdev=net0 \
  • Activer le service SSH
# systemctl start ssh
  • Pour accéder à l'invité depuis l'hôte

$ ssh localhost -p5022
  • Sous réserve de la place restante dans la partition Racine de l'image, mettre à jour et ajouter les paquets. A noter que si le noyau est mis à jour, il sera nécessaire de l'extraire à nouveau et de le passer en argument aux options -kernel et initrd si l'on souhaite que le démarrage s'effectue avec le noyau mis à jour

Informations sur le système émulé

$ arch
aarch64

$ cat /etc/debian_version
10.6

$ cat /etc/issue
Debian GNU/Linux 10 \n \l

$ uname -r
4.19.0-10-arm64

$ uname -a
Linux rpi 4.19.0-10-arm64 #1 SMP Debian 4.19.132-1 (2020-07-24) aarch64 GNU/Linux

$ lsblk -f
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
vda
├─vda1
│ vfat RASPIFIRM
│ 8FBE-F858 194.1M 35% /boot/firm
└─vda2
ext4 RASPIROOT
1b9125ba-e961-40bf-a9db-75f20fa8d9fa 2.5G 27% /

$ free -h
total used free shared buff/cache available
Mem: 993Mi 48Mi 723Mi 1.0Mi 221Mi 873Mi
Swap: 0B 0B 0B

$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff

$ ip route
default via 10.0.2.2 dev eth0
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15

Image RaspBerry Pi 4

Procéder comme pour l'image RaspBerry Pi 3

Extraction du noyau

  • Boucles de périphérique, montage et extraction du noyau et de la ligne de commande
$ sudo losetup -P /dev/loop99 20200909_raspi_4.img 
$ sudo mount /dev/loop99p2 /mnt
$ sudo mount /dev/loop99p1 /mnt/boot/firmware/

$ cp /mnt/boot/initrd.img* /mnt/boot/vmlinuz* ./
$ cp /mnt/boot/firmware/cmdline.txt ./

$ ls -l
total 1269792
-rw-r--r-- 1 philippe philippe 1572864000 oct. 5 18:32 20200909_raspi_4.img
-rw-r--r-- 1 philippe philippe 367 oct. 5 14:45 20200909_raspi_4.xz.sha256.asc
-rwxr-xr-x 1 philippe philippe 115 oct. 5 18:32 cmdline.txt
-rw-r--r-- 1 philippe philippe 28172439 oct. 5 18:31 initrd.img-5.8.0-1-arm64
-rw-r--r-- 1 philippe philippe 22421360 oct. 5 18:31 vmlinuz-5.8.0-1-arm64

$ cat cmdline.txt
console=tty0 console=ttyS1,115200 root=LABEL=RASPIROOT rw elevator=deadline fsck.repair=yes net.ifnames=0 rootwait
  • Notes :
    • la ligne de commande du système a été extraite pour information seulement et ne sera pas utilisée dans l'émulation
    • il y a une erreur dans la ligne de commande du système console=ttyS1 doit être remplacé par console=ttyA1
  • Démontage
$ sudo umount /mnt/boot/firmware /mnt
$ sudo losetup -d /dev/loop99

Lancement de l'émulation

  • La carte Raspberry Pi 4 est équipée d'un processeur Broadcom BCM2711, quad-core Cortex-A72 (ARM v8) 64-bit et de 2, 4 ou 8 GB de RAM. Dans ce qui suit, on affectera 2GB à l'émulation
#!/usr/bin/env bash

RASPI=20200909_raspi_4.img VMLINUZ=vmlinuz-5.8.0-1-arm64 INITRD=initrd.img-5.8.0-1-arm64
qemu-system-aarch64 \ -kernel $PWD/$VMLINUZ \ -initrd $PWD/$INITRD \ -m 2048 -M virt \ -cpu cortex-a72 \ -serial stdio \ -append "rw root=/dev/vda2 console=ttyAMA0 loglevel=8 rootwait fsck.repair=yes memtest=1" \
-drive file=$RASPI,format=raw,if=sd,id=hd-root \ -device virtio-blk-device,drive=hd-root \ -netdev user,id=net0,hostfwd=tcp::5022-:22 \ -device virtio-net-device,netdev=net0 \ -no-reboot

exit

Lancer le script et procéder comme pour l'émulation de l'OS RaspBerry Pi 3

Informations sur le système installé

$ uname -r
5.8.0-1-arm64

$ uname -a
Linux rpi 5.8.0-1-arm64 #1 SMP Debian 5.8.7-1 (2020-09-05) aarch64 GNU/Linux

$ free
total used free shared buff/cache available
Mem: 1972732 60416 1792972 2628 119344 1779816
Swap: 0 0 0