Émulation en espace utilisateur d'un système ARM sur un hôte amd64 - Qemu-user-static

Création : Hôte : Debian 11.1 Bulleseye, invités :

Le paquet qemu-user-static et ses dépendances permet d'exécuter de façon transparente un programme binaire d'architecture étrangère sur une architecture hôte

Cette propriété peut-être utilisée pour émuler un système arm sur un hôte amd64 : le système arm (disque ou image) est monté dans le système hôte, un changement de racine (chroot) permet d'accéder au système en mode émulé. Il est alors possible par exemple de mettre à jour, ajouter ou supprimer des applications

Cette émulation se limite à l'espace utilisateur du système arm et ne permet donc pas d'émuler l'amorçage ou le matériel de la plateforme

Dans ce qui suit, la méthode est appliquée à trois systèmes pour Raspberrypi 4:

Références

Sommaire

1 - Préparation

$ sudo aptitude install -t bulleseye-backports qemu qemu-user-static binfmt-support

$ aptitude versions ~iqemu-user-static
Paquet qemu-user-static:
i 1:6.1+dfsg-6~bpo11+1 bullseye-backports 100

2 - Montage

$ lsblk -f /dev/mmcblk0
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
mmcblk0

├─mmcblk0p1
│ vfat FAT32 boot 4AD7-B4D5
├─mmcblk0p2
│ ext4 1.0 rootfs
│ 2887d26c-6ae7-449d-9701-c5a4018755b0
└─mmcblk0p3
ext4 1.0 Musique
570490bb-eb76-4906-bce3-f64188c2a54
$ sudo momunt /dev/mmcblk0p2 /mnt

$ cat /mnt/etc/fstab
proc /proc proc defaults 0 0

PARTUUID=90c80064-01 /boot vfat defaults
PARTUUID=90c80064-02 / ext4 defaults,noatime 0 1
# a swapfile is not a swap partition, no line here
# use dphys-swapfile swap[on|off] for that

PARTUUID=90c80064-03 /var/lib/mopidy/Music ext4 defaults 0 2
$ sudo mount PARTUUID=90c80064-01 /mnt/boot
$ sudo mount PARTUUID=90c80064-03 /mnt/var/lib/mopidy/Music

3 - Chroot

$ for i in proc sys run dev dev/pts; do sudo mount --bind /$i /mnt/$i; done 
$ LC_ALL=C sudo chroot /mnt /bin/bash

Machine

# uname --machine
armv7l

Distribution

# cat /etc/issue          
Raspbian GNU/Linux 11 \n \l

Version

# cat /etc/debian_version 
11.1

Sources

# cat /etc/apt/sources.list
deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi

# cat /etc/apt/sources.list.d/raspi.list
deb http://archive.raspberrypi.org/debian/ buster main
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspberrypi.org/debian/ buster main

Noyau

# ls -l vmlinuz
lrwxrwxrwx 1 root root 26 sept. 21 14:11 vmlinuz -> boot/vmlinuz-5.8.0-1-arm64

Nom d'hôte

# cat /etc/hostname 
rpi4-20200909
# apt update
# apt upgrade

4 - Démontage

# exit
$ for i in dev/pts dev run sys proc; do sudo umount /mnt/$i; done
$ sudo umount /mnt/var/lib/mopidy/Music /mnt/boot /mnt

Annexe 1 - Émulation de l'image Raspberry Pi4 arm64 Debian unofficial

1.1 - Préparation de l'image

Pi O$ wget https://raspi.debian.net/verified/20200909_raspi_4.img.xz
$ unxz 20200909_raspi_4.img.xz
$ sudo parted 20200909_raspi_4.img print
Model: (file)
Disk xxxxx/20200909_raspi_4.img: 1573MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number Start End Size Type File system Flags
1 1049kB 315MB 314MB primary fat16 lba
2 315MB 1573MB 1258MB primary ext4

La partition 1 est la partition d'amorçage (boot et firmwares)

La partition 2 est la partition racine.

$ truncate -s 6000MiB 20200909_raspi_4.img
$ dd if=/dev/zero bs=1MiB count=3000 of=20200909_raspi_4.img conv=notrunc oflag=append
$ dd if=/dev/zero bs=1MiB count=8000 of=raspi4.img

et en y copiant l'image initiale

$ dd if=20200909_raspi_4.img of=raspi4.img conv=notrunc

La suite s'effectuera avec l'image raspi4.img.

$ sudo parted raspi4.img print free
...
Number Start End Size Type File system Flags
16,4kB 1049kB 1032kB Free Space
1 1049kB 315MB 314MB primary fat16 lba
2 315MB 1573MB 1258MB primary ext4
1573MB 8389MB 6816MB Free Space
$ sudo parted raspi4.img resizepart 2 100%
$ sudo losetup --show -P -f raspi4.img 
/dev/loop14

$ lsblk -f /dev/loop14
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
loop14
├─loop14p1 vfat RASPIFIRM C80B-157C
└─loop14p2 ext4 RASPIROOT 56e94ab7-95ad-49eb-8d23-ee52ff867e32
$ sudo e2fsck -f /dev/loop14p2
$ sudo resize2fs /dev/loop14p2

1.2 - Montage

$ sudo /dev/loop14p2 /mnt
$ df -h /mnt
Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur
/dev/loop14p2 7,4G 572M 6,5G 8% /mnt
$ cat /mnt/etc/fstab
# The root file system has fs_passno=1 as per fstab(5) for automatic fsck.
LABEL=RASPIROOT / ext4 rw 0 1
# All other file systems have fs_passno=2 as per fstab(5) for automatic fsck.
LABEL=RASPIFIRM /boot/firmware vfat rw 0 2
proc /proc proc defaults 0 0
$ sudo mount /dev/loop14p1 /mnt/boot/firmware

1.3 - Chroot

Architecture

# uname -m
aarch64

Distribution

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

Version

# cat /etc/debian_version 
10.5

Sources des paquets

# cat /etc/apt/sources.list
deb http://raspbian.raspberrypi.org/raspbian/ bullseye main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi

# cat /etc/apt/sources.list.d/raspi.list
deb http://archive.raspberrypi.org/debian/ bullseye main
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspberrypi.org/debian/ buster main

# cat /etc/apt/sources.list.d/raspi.list
deb http://archive.raspberrypi.org/debian/ bullseye main
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspberrypi.org/debian/ buster main
root@debian:/# cat /etc/apt/sources.list.d/mopidy.list
# Mopidy APT archive
# Built on Debian 10 (buster), compatible with Ubuntu 19.10 and newer
deb https://apt.mopidy.com/ buster main contrib non-free
#deb-src https://apt.mopidy.com/ bullseye main contrib non-free

Noyau

# ls -l vmlinuz
lrwxrwxrwx 1 root root 26 sept. 21 14:11 vmlinuz -> boot/vmlinuz-5.8.0-1-arm64

Nom d'hôte

# cat /etc/hostname 
rpi4-20200909

1.4 - Démontage

$ sudo umount /mnt/boot/firmware /mnt
$ sudo losetup -d /dev/loop14
$ lsblk -f /dev/loop14

Annexe 2 - Émulation de l'image Raspberry Pi4 officielle

La méthode pour l'émulation de l'image RaspBerry Pi4 officielle est identique à celle pour l'image Debian. Les principaux écarts et résultats sont indiqués ci-après

$ wget http://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2020-08-24/2020-08-20-raspios-buster-armhf-lite.zip
$ lsblk -f /dev/loop14
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
loop14
├─loop14p1 vfat boot 4AD7-B4D5
└─loop14p2 ext4 rootfs 2887d26c-6ae7-449d-9701-c5a4018755b0
$ cat /mnt/etc/fstab 
proc /proc proc defaults 0 0
PARTUUID=907af7d0-01 /boot vfat defaults 0 2
PARTUUID=907af7d0-02 / ext4 defaults,noatime 0 1

Machine

# uname --machine
armv7l

Distribution

# cat /etc/issue          
Raspbian GNU/Linux 10 \n \l

Version

# cat /etc/debian_version 
10.4

Sources

# cat /etc/apt/sources.list
deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi

# cat /etc/apt/sources.list.d/raspi.list
deb http://archive.raspberrypi.org/debian/ buster main
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspberrypi.org/debian/ buster main