• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 23/12/2019

Émulez une Raspberry PI avec QEMU

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Installez QEMU

Vous venez d'utiliser QEMU pour émuler un processeur ARM et ainsi exécuter du code ARM sur une plateforme x86. Continuons avec l'émulation d'une plateforme ARM complète, et commençons tout d'abord avec une Raspberry PI 2.

Commencez par installer l'émulateur QEMU pour plateforme ARM.

sudo apt-get install qemu-system-arm

Puis listez l'ensemble des plateformes (machines) supportées par QEMU.

qemu-system-arm -machine help

Vous obtenez ainsi la liste des plateformes ARM que QEMU peut émuler.

QEmu : liste des plateformes supportées

Dans notre cas, la ligne qui nous intéresse est celle correspondant à la Raspberry PI 2.

raspi2 Raspberry Pi 2

Listez ensuite les processeurs supportés par l'émulateur pour cette plateforme.

qemu-system-arm -machine raspi2 -cpu help

Vous obtenez la liste des processeurs ARM supportés.

QEmu : liste des processeurs supportées

Dans notre cas, le processeur dont nous avons besoin pour émuler une Raspberry PI 1 est l'arm1176.

Émulez Raspbian avec le support officiel de QEMU

QEMU offre dans ses dernières versions l'émulation de la carte Raspberry PI 2 et il permet normalement de démarrer une image de Raspbian sans modification. Nous allons donc tester cette émulation. Récupérez tout d'abord une image de Raspbian :

cd ~/Development-tools/
mkdir raspbian
cd raspbian
wget http://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2018-04-19/2018-04-18-raspbian-stretch-lite.zip
unzip 2018-04-18-raspbian-stretch-lite.zip

Vous devez maintenant extraire le noyau et le fichier décrivant le matériel présent sur la carte Raspberry PI 2. L'image Raspbian est l'image d'une carte SD qui contient deux partitions. La première, une partition au format VFAT, contient le chargeur de démarrage (u-Boot), le noyau (kernel7.img) et les fichiers de description du matériel (fichier .dtb). La seconde partition contient l'image du système GNU/Linux Raspbian. Pour extraire les deux fichiers qui nous intéressent, vous aller monter l'image de Raspbian dans un répertoire temporaire  :

sudo mkdir /mnt/rpi
sudo losetup -f --show -P ~/Development-tools/raspbian/2018-04-18-raspbian-stretch-lite.img
sudo mount /dev/loop0p1 /mnt/rpi
cp /mnt/rpi/kernel7.img /mnt/rpi/bcm2709-rpi-2-b.dtb ~/Development-tools/raspbian/
sudo umount /mnt/rpi
sudo losetup -d /dev/loop0

Pour émuler une carte Raspberry 2 avec QEMU, vous allez utiliser cette commande :

qemu-system-arm -M raspi2 \
                -cpu cortex-a7 \
                -append "rw earlyprintk loglevel=8 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2" \
                -dtb ~/Development-tools/raspbian/bcm2709-rpi-2-b.dtb \
                -drive file=~/Development-tools/raspbian/2018-04-18-raspbian-stretch-lite.img,if=sd,format=raw \
                -kernel ~/Development-tools/raspbian/kernel7.img \
                -m 1G \
                -smp 4

qemu-system-arm est l'exécutable de QEMU permettant d'émuler une architecture ARM 32 bits. Regardons les paramètres en détail :

  • -M : indique la "machine" que l'on souhaite émuler, ici une carte Raspberry PI 2 ;

  • -cpu : permet d'indiquer le processeur à émuler, dans notre cas un Cortex A7 ;

  • -append : est utilisé pour passer des paramètres au noyau, le paramètre important étant root= qui précise le nom du périphérique qui contient la racine du système GNU/Linux (seconde partition de la carte SD) ; 

  • -dtb : correspond au fichier décrivant le matériel présent sur la carte (Device Tree Blob) ;

  • -drive : permet d'émuler un lecteur SD contenant l'image de la Raspbian ;

  • -kernel : le noyau qui sera chargé par le chargeur de démarrage ;

  • -m : la taille de la RAM, 1 Go pour une Raspberry PI 2 ;

  • -smp : le nombre de cœurs du processeur, ici 4.

Tentez de démarrer l'image de la Raspbian que vous venez de télécharger en exécutant cette commande :

Premier essai non concluant
Premier essai non concluant

Dans mon cas, QEMU charge correctement le noyau qui termine son exécution avec un magnifique kernel panic !!! En effet, le support natif des cartes Raspberry est en cours de développement et, en fonction de la version de QEMU qui a été installée, cette émulation fonctionne correctement ou se termine avec une erreur lors de l'exécution du noyau. Mais ne vous inquiétez pas, cette émulation étant trop instable actuellement, nous allons donc utiliser une autre possibilité de QEMU.

Émulez Raspbian avec un noyau modifié

Afin d'émuler une Raspberry PI 2 sans crash intempestif, il est possible d'utiliser un noyau modifié pour exécuter une Raspbian. Contrairement à l'émulation native, cette solution ne permet pas d'émuler tous les composants d'une Raspberry, notamment les GPIO, mais comme nous n'aurons pas besoin de cela dans ce cours, nous utiliserons cette deuxième possibilité.

Commencez par récupérer le noyau modifié pour être compatible avec QEMU :

cd ~/Development-tools/
git clone https://github.com/dhruvvyas90/qemu-rpi-kernel

Puis récupérez une version de Raspbian compatible avec ce noyau modifié.

cd raspbian
wget http://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-12-01/2017-11-29-raspbian-stretch-lite.zip
unzip 2017-11-29-raspbian-stretch-lite.zip

Créez un script, nommé start-qemu-rpi.sh, qui vous permettra d'exécuter votre image de Raspbian en émulant une Raspberry PI :

cd ~/Development-tools/
nano start-qemu-rpi.sh

Voici le contenu de ce script :

#!/bin/bash 
qemu-system-arm -M versatilepb \
                -cpu arm1176 \
                -kernel qemu-rpi-kernel/kernel-qemu-4.9.59-stretch \
                -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" \
                -hda raspbian/2017-11-29-raspbian-stretch-lite.img \
                -m 256 \
                -dtb qemu-rpi-kernel/versatile-pb.dtb \
                -no-reboot \
                -net nic -net user,hostfwd=tcp::5022-:22 

Ce script permettra de lancer l'émulateur qemu-system-arm en émulant une carte versatilepb qui est une ancienne carte embarquée de développement, compatible avec GNU/Linux. Notre objectif est de réussir à démarrer une image de Raspbian avec QEMU, afin de tester notre future image sans passer par une vraie carte Raspberry. Pour cela, nous utilisons le processeur arm1176 qui est celui disponible sur Raspberry PI 1. Nous n'émulons pas une carte SD mais un disque dur, notre partition racine correspondra donc au périphérique /dev/sda2.

Finalement, avec l'option -net, nous créons une carte réseau virtuelle qui permettra de rediriger le port 5022 local vers le port 22 de l'image, et ainsi de se connecter en SSH sur la carte émulée.

Rendez ensuite ce script exécutable, et exécutez-le :

chmod +x start-qemu-rpi2.sh
./start-qemu-rpi2.sh

Une fenêtre graphique s'ouvre et vous assistez tout d'abord au chargement du noyau modifié. Vous pouvez remarquer les fameuses framboises en haut à gauche, symbole de la carte Raspberry. À la suite du chargement du noyau, le système démarre et vous obtenez finalement une bannière de connexion.

Lancement de raspbian avec qemu
Lancement de Raspbian avec QEMU

Vous avez maintenant une Raspberry PI "virtuelle" fonctionnelle.

Exemple de certificat de réussite
Exemple de certificat de réussite