![]() |
M2 SETI B4 / MS SE SE758 |
L’objectif de ce premier TP est de prendre en main les éléments de base pour démarrer un système Linux minimaliste :
initramfs
à l’aide de
BusyBoxConvention : Dans la suite du texte, lorsque vous avez des
commandes à taper dans un terminal, elles sont indiquées avec un
caractère $
en début de ligne. Ce caractère $
au début des lignes de commande représente l’invite de commande,
c’est-à-dire les caractères affichés par votre interpréteur de commande
pour vous inviter à taper une commande (ils varient d’un interpréteur de
commande à un autre et en fonction de votre configuration). Ce caractère
$
(uniquement au début de la ligne) n’est donc pas à
taper.
Nous vous recommandons, pour la suite du TP, de travailler dans un
nouveau répertoire. Dans la suite du texte (et dans les TP ultérieurs),
nous nous y référerons grâce à la variable d’environnement
TPROOT
.
Si vous êtes sur votre machine personnelle, vous
pouvez créer le répertoire où vous le souhaitez et lui donnez le nom que
vous voulez. Par exemple, pour créer un répertoire
seti-b4-tp
dans votre répertoire personnel, vous pouvez
taper :
$ export TPROOT=~/seti-b4-tp
$ mkdir $TPROOT
$ cd $TPROOT
Attention, si vous ouvrez un autre terminal, vous aurez besoin de
redéfinir la variable TPROOT
(à l’aide de la première
ligne).
Si vous êtes sur une machine de TP de l’école,
attention, la taille de votre répertoire personnel est très limitée
(quelques gigaoctets). Or nous aurons besoin de plus de place.
Heureusement, les machines disposent d’un répertoire local que vous
pouvez utiliser pour stocker des fichiers volumineux. Néanmoins,
attention, les fichiers dans ce répertoire ne sont pas sauvegardés et ne
sont accessibles que depuis la machine que vous utilisez (contrairement
à votre répertoire personnel qu iest accessible depuis n’importe quelle
machine de TP). Utilisez les commandes suivantes pour créer un
répertoire de travail en local (remplacez xxx
par votre nom
d’utilisateur) :
$ export TPROOT=/home/users/xxx/seti-b4-tp
$ mkdir $TPROOT
$ cd $TPROOT
Si la commande mkdir
échoue, n’allez pas plus loin.
Attention, si vous ouvrez un autre terminal, vous aurez besoin de
redéfinir la variable TPROOT
(à l’aide de la première
ligne).
Pour simuler un système embarqué complet à base de processeur ARM, nous allons utiliser QEMU. En plus de ne pas avoir besoin de matériel physique pour expérimenter, Qemu permet également de facilement tester, mais aussi débugger votre système embarqué.
Plus précisément, nous allons utiliser qemu-system-arm
qui est un émulateur de machine complète, en l’occurrence, une carte de
développement Arm Versatile Express munie d’une carte
d’extension CoreTile Express A9x4 à base de
Cortex-A9.
Les détails de ce que QEMU simule concernant cette carte sont disponibles dans la documentation : https://www.qemu.org/docs/master/system/arm/vexpress.html.
Nous utiliserons une version particulière de
qemu-system-arm
(elle ajoute à QEMU un périphérique émulé
pour lequel vous allez écrire un pilote de périphérique dans la suite du
cours).
Téléchargez :
Placez l’exécutable téléchargé dans votre répertoire
$TPROOT
, puis vérifiez que les droits sont corrects pour
l’exécution :
$ chmod u+x qemu-system-arm
Normalement, cet exécutable utilise des bibliothèques partagées qui devraient être disponibles sur votre machine. Néanmoins, vérifiez que toutes les bibliothèques sont présentes en tapant :
$ ldd qemu-system-arm
Si vous désirez, le code source de QEMU ainsi que les modifications
apportées sont disponibles dans la branche adxl345
du dépôt
https://gitlab.telecom-paris.fr/guillaume.duc/qemu.
Toutes les couches logicielles que nous allons compiler (noyau,
outils, etc.) sont destinées à être exécutées sur une machine à base de
processeur ARM Cortex-A. Or, il est très probable que vous réalisiez le
TP sur une machine à base de processeur x86
ou
x86_64
.
Donc si vous compilez en utilisant le compilateur classique de votre
machine, vous obtiendrez du code machine pour processeur
x86
ou x86_64
qui ne pourra donc pas
s’exécuter sur un processeur ARM.
Vous devrez donc utiliser un cross-compilateur, c’est-à-dire
un compilateur qui s’exécute sur une architecture A (ici
x86_64
) mais qui produit du code pour une architecture B
(ici arm
).
Nous verrons comment construire un cross-compilateur dans un
cours ultérieur, pour le moment, nous utiliserons la chaîne
arm-linux-gnueabihf
fournie par Linaro.
Si vous êtes sur votre machine personnelle :
Téléchargez-la ici : https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/arm-linux-gnueabihf/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz
Puis décompressez-la quelque part (par exemple dans votre répertoire
de TP) et ajoutez le chemin
/.../gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin
(en remplaçant /.../
par le chemin correct) dans votre
variable d’environnement PATH
.
Si vous êtes sur une machine des salles de TP :
La chaîne étant déjà installée, ajoutez simplement le répertoire
/comelec/softs/opt/gnu_tools_for_arm/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/
dans votre variable d’environnement PATH
:
$ export PATH=$PATH:/comelec/softs/opt/gnu_tools_for_arm/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/
Si vous êtes sur votre machine personnelle, pour réaliser ce TP, et les suivants, vous aurez besoin d’un certain nombre d’outils classiques de développement, certains étant probablement déjà installés sur votre distribution.
Pour Debian/Ubuntu, installez les paquets suivants :
build-essential
libncurses-dev
et libncurses5-dev
file
cpio
unzip
rsync
bc
Le composant le plus important d’un système à base de Linux est… le noyau Linux lui-même.
Les versions officielles du noyau Linux sont téléchargeables depuis https://www.kernel.org. La page d’accueil permet un accès rapide à :
Les sources peuvent être récupérées sous forme d’une archive
contenant une version donnée (format .tar.xz
). Une fois
décompressées, les sources d’une version prennent un peu plus d’1
Gio.
Il est également possible (et même conseillé si on veut développer),
de récupérer directement le dépôt git
officiel incluant
tout l’historique (depuis que les développeurs du noyau utilisent
git
!) :
Note : ne pas taper les commandes ci-dessous, elles ne sont données qu’à titre indicatif pour le moment.
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
ou bien (par exemple si un pare-feu paranoïaque bloque l’accès au
protocole git
(port TCP 9418)) :
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
En décembre 2021, une copie du dépôt git officiel prend environ 3,8 Gio.
De nombreux fabricants maintiennent leurs propres versions des sources du noyau incluant le support pour leurs produits quand il n’est pas encore intégré aux versions officielles.
Par exemple, les sources du noyau Linux pour les FPGA SoC d’Altera sont disponibles ici : https://github.com/altera-opensource/linux-socfpga.
De même, certaines distributions maintiennent des versions divergentes du noyau pour diverses raisons.
Note préliminaire : les commandes contenues dans cette section sont données à titre d’exemple et ne sont pas à exécuter.
Le noyau Linux est extrêmement versatile (il est conçu pour fonctionner sur de nombreuses architectures, depuis un petit système embarqués jusqu’à de gros supercalculateurs, il gère de très nombreux périphériques différents, de nombreux protocoles réseaux, etc.). Il dispose donc d’un système de configuration permettant d’adapter le noyau aux besoins de l’utilisateur en ne sélectionnant que ce qui est nécessaire.
Plusieurs cibles du Makefile
principal du noyau
permettent de créer et de modifier cette configuration :
make config
: outil de base textuel, toutes les options
sont présentées les unes après les autres (très peu pratique)make menuconfig
: outil semi-graphique (nécessite la
bibliothèque ncurses
et ses entêtes)make nconfig
: outil semi-graphique (nécessite la
bibliothèque ncurses
et ses entêtes)make xconfig
: outil graphique basé sur Qt (nécessite
les bibliothèques de développement Qt)make gconfig
: outil graphique basé sur GTK+ (nécessite
les bibliothèques de développement GTK+ 2.0)Si aucun fichier de configuration n’existe (ce qui est le cas lorsque
l’on récupère les sources officielles), ces outils vont chercher s’il
existe un fichier dont le nom est de la forme
/boot/config-*
et le prendre comme base. Sinon, les valeurs
par défaut des paramètres sont choisies.
Si vous disposez déjà d’un fichier de configuration, issu par exemple
d’une version précédente du noyau, la commande
make oldconfig
peut se révéler très utile. Elle supprime
les options qui n’existent plus et demande l’avis de l’utilisateur
uniquement pour les nouvelles options.
Enfin, un certain nombre de fichiers de configuration par défaut pour
de nombreuses cartes embarquées sont disponibles dans le répertoire
arch/xxx/configs
(où xxx
représente une
architecture, comme arm
). Pour les utiliser, il suffira de
taper make yyy_defconfig
.
La configuration est stockée, sous un format textuel simple
(cle=valeur
), dans le fichier .config
.
Plusieurs types sont possibles pour une valeur :
bool
: vrai (y
) / faux (non déclaré :
# XXX is not set
)tristate
: vrai (y
) / module
(m
) / faux (non déclaré :
# XXX is not set
)string
: chaîne de caractèreshex
: valeur numérique représentée sous forme
hexadécimale (base 16)int
: valeur numérique représentée sous forme décimale
(base 10)Des options peuvent dépendre d’autres options (exemple : le support des périphériques de stockage USB (mass storage device) dépend du support de l’USB).
Pour les types bool
ou tristate
, la valeur
a la signification suivante :
Voici un extrait d’un fichier de configuration du noyau :
#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
CONFIG_USB_XHCI_HCD=m
# CONFIG_USB_XHCI_PLATFORM is not set
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_EHCI_PCI=m
Note préliminaire : les commandes contenues dans cette section sont données à titre d’exemple et ne sont pas à exécuter.
Pour compiler le noyau pour une architecture identique à celle sur
laquelle est lancée le compilateur, il suffit de lancer la commande
make
à la racine du noyau.
Il est possible de faire en sorte que tous les fichiers produits lors de la compilation soient stockés dans un autre répertoire (par exemple si les sources sont en lecture seule pour l’utilisateur ou si on ne veut pas les polluer) :
$ make O=/home/toto/build menuconfig
$ make O=/home/toto/build
Plusieurs fichiers sont produits par la compilation dont notamment :
arch/<arch>/boot/*Image
vmlinux
.
Elle est notamment utilisée pour le debug*.ko
) répartis dans
toute l’arborescence du noyauL’installation du noyau se fait à l’aide de la cible
install
du Makefile
:
# make install
ou, si vous avez compilé le noyau en utilisant un répertoire à part :
# make O=/home/toto/build install
Cette commande effectue les opérations suivantes :
/boot/vmlinuz-<version>
/boot/config-<version>
/boot/System.map-<version>
L’accès en écriture au répertoire /boot
n’étant
normalement pas possible pour un utilisateur normal, la commande
make
a besoin des privilèges administrateurs pour pouvoir
réaliser l’installation.
L’installation des modules se fait à l’aide de la cible
modules_install
du Makefile
:
# make modules_install
Elle installe les modules (fichiers *.ko
ainsi que les
informations de dépendance entre modules, de table des symboles et
d’alias) dans /lib/modules/<version>
.
Il est parfois nécessaire de compiler le noyau pour une architecture différente de celle sur laquelle s’effectue la compilation. On parle alors de cross-compilation ou compilation croisée.
Deux variables sont utilisées par le Makefile
pour
permettre la compilation croisée :
ARCH
: nom de l’architecture cible (telle qu’elle
apparaît dans arch/
)CROSS_COMPILE
: préfixe de la chaîne de compilation
(exemple arm-linux-gnueabihf-
si le compilateur s’appelle
arm-linux-gnueabihf-gcc
)Ces deux variables doivent être passées à chaque invocation d’une
cible du Makefile
, soit en les spécifiant sur la ligne de
commande, soit en les exportant en tant que variables
d’environnement.
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
ou bien :
$ export ARCH=arm
$ export CROSS_COMPILE=arm-linux-gnueabihf-
$ make menuconfig
$ make
Trois cibles du Makefile
sont disponibles pour permettre
le nettoyage des sources :
clean
: Efface la plupart des fichiers générés, à
l’exception de la configuration (.config
) et des fichiers
nécessaire pour compiler des modules externesmrproper
: Efface tous les fichiers générés, y compris
.config
(attention)distclean
: Comme mrproper
mais efface en
plus tous les fichiers de sauvegarde des éditeurs (*~
par
exemple), les fichier de rejet de patch, etc.$ cd $TPROOT
$ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.6.tar.xz
$ tar xJf linux-5.15.6.tar.xz
$ cd linux-5.15.6
$ export ARCH=arm
$ export CROSS_COMPILE=arm-linux-gnueabihf-
build
pour la compilation) :$ make O=build vexpress_defconfig
$ make O=build menuconfig
Parcourez rapidement la configuration. Nous aurons besoin dans la suite d’une option qui n’est pas activée dans la configuration par défaut : Support for uevent helper (dans Device Drivers -> Generic Driver Options).
Compilez le noyau :
$ make O=build
Deux fichiers importants sont produits par la compilation :
build/arch/arm/boot/zImage
: l’image compressée du
noyaubuild/arch/arm/boot/dts/vexpress-v2p-ca9.dtb
: l’arbre
des périphérique par défaut pour la carte$ cd $TPROOT
$ ./qemu-system-arm -machine vexpress-a9 -nographic -kernel \
-dtb \
linux-5.15.6/build/arch/arm/boot/zImage linux-5.15.6/build/arch/arm/boot/dts/vexpress-v2p-ca9.dtb
Cette commande lance QEMU en lui indiquant le type de machine à
émuler (vexpress-a9
), l’image du noyau à utiliser
(linux-5.15.6/build/arch/arm/boot/zImage
) et l’arbre des
périphériques à utiliser
(linux-5.15.6/build/arch/arm/boot/dts/vexpress-v2p-ca9.dtb
).
Dans ce mode, QEMU va placer en mémoire RAM l’image du noyau et le DTB,
et lancer l’exécution du noyau, comme le ferait un bootloader (voir le
cours sur le démarrage d’un système Linux).
Vous devriez voir les messages de démarrage du noyau s’afficher (ils s’affichent car QEMU redirige vers le terminal la première liaison série de la carte émulée, qui se trouve être celle utilisée par le noyau pour envoyer ses messages). Le noyau va paniquer et s’arrêter. Pourquoi ?
Quand QEMU fonctionne, tout ce que vous tapez dans votre terminal est
envoyé à votre machine virtuelle par l’intermédiaire de la liaison série
émulée. Vous pouvez accéder à la console de QEMU en tapant
ctrl-a c
. Puis dans cette console, tapez quit
(ou q
) pour arrêter QEMU.
Le noyau ne trouve pas de système de fichiers. Nous allons donc, dans
un premier temps, lui fournir une image mémoire initramfs
et un premier petit processus init
.
$ cd $TPROOT
$ mkdir initramfs_simple
$ cd initramfs_simple
init.c
avec le contenu suivant (vous
êtes libres d’adapter si vous voulez) :#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
("Hello world!\n");
printf(10);
sleep}
$ arm-linux-gnueabihf-gcc -static init.c -o init
Note : nous utilisons ici -static
pour lier la
bibliothèque C avec l’exécutable afin que ce dernier contiennent tout ce
dont il a besoin pour s’exécuter (dans le cas contraire, il aurait fallu
copier dans l’archive la bibliothèque standard, l’éditeur de liens
dynamique et le chargeur dynamique).
initramfs
à l’aide de
cpio
(profitez-en pour regarder la page de manuel de
cpio
pour comprendre le fonctionnement de la ligne de
commande suivante) :$ echo init | cpio -o -H newc | gzip > test.cpio.gz
$ cd ..
$ ./qemu-system-arm -machine vexpress-a9 -nographic -kernel \
\
linux-5.15.6/build/arch/arm/boot/zImage \
-dtb linux-5.15.6/build/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -initrd initramfs_simple/test.cpio.gz
Vous devriez voir que votre programme est exécuté puis, quand il se
termine (au bout de quelques secondes), le noyau panique
(init
n’est pas censé se terminer).
BusyBox se décrit lui-même
comme le couteau suisse pour les systèmes Linux embarqués. Il combine
des versions simplifiées de nombreux utilitaires Unix courants
(init
, mount
, cp
,
ls
, ifconfig
…) dans un seul petit exécutable.
Il fournit donc à lui seul, un environnement quasiment complet pour de
petits systèmes embarqués.
Nous allons donc utiliser BusyBox pour faire une image mémoire initiale un peu plus fonctionnelle que la précédente.
$ cd $TPROOT
$ wget https://busybox.net/downloads/busybox-1.34.1.tar.bz2
$ tar xjf busybox-1.34.1.tar.bz2
$ cd busybox-1.34.1
$ export ARCH=arm
$ export CROSS_COMPILE=arm-linux-gnueabihf-
$ make defconfig
$ make menuconfig
Dans la configuration, pensez à activer l’option Build Static Binary dans le menu Settings (comme précédemment, on veut éviter d’avoir à gérer les bibliothèques dynamiques pour le moment).
$ make
$ make install
Nous allons maintenant préparer une image initramfs
un
peu plus complète intégrant BusyBox.
$ cd $TPROOT
$ mkdir initramfs_busybox
$ cd initramfs_busybox
mknod
), ce qui est normalement interdit à un utilisateur
normal. Nous allons donc faire ces opérations dans un environnement
virtuel nous permettant de le faire uniquement dans le but de créer une
archive correcte :$ fakeroot /bin/bash
$ cp -r ../busybox-1.34.1/_install/* .
Vous vous retrouvez avec des répertoires bin
,
sbin
, usr/bin
et usr/sbin
qui
contiennent des liens symboliques portant le nom des commandes
classiques Linux (cp
, insmod
,
mount
…) vers le seul réel exécutable :
bin/busybox
. Busybox se sert du nom utilisé pour lancer la
commande (qui, pour rappel, est le premier argument récupéré depuis la
ligne de commande) pour identifier ce qu’il doit faire. Par exemple,
s’il est appelé via bin/cp
, il se comportera comme la
commande cp
.
linuxrc
à la racine de votre
image. Pour rappel, c’est cet exécutable que le noyau va lancer depuis
une image initrd
. Or nous sommes en train de construire une
image initramfs
, donc renommons ce lien symbolique :$ rm linuxrc
$ ln -s bin/sh init
$ mkdir proc sys tmp root var mnt dev etc
dev
quelques fichiers
spéciaux pour les terminaux (si vous êtes sur votre machine personnelle,
exécutez ces commandes en tant que root
avec
su
ou sudo
)$ mknod dev/console c 5 1
$ mknod dev/tty1 c 4 1
$ mknod dev/tty2 c 4 2
$ mknod dev/tty3 c 4 3
$ mknod dev/tty4 c 4 4
etc
:$ cd etc
$ cp ../../busybox-1.34.1/examples/inittab .
$ mkdir init.d
$ cd init.d
$ cat <<EOF > rcS
#!/bin/sh
mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
mkdir -p /var/lock
ifconfig lo 127.0.0.1
EOF
$ chmod 755 rcS
$ cd ..
$ cat <<EOF > fstab
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
EOF
Le fichier etc/inittab
est tiré directement de l’exemple
fourni par BusyBox. Il lui indique ce qu’il doit exécuter au démarrage
et à l’arrêt du système et les terminaux à ouvrir.
Le fichier etc/init.d/rcS
est un script exécuté par
BusyBox au démarrage. Tel que rempli ci-dessus, il monte les systèmes de
fichiers décrits dans /etc/fstab
, active mdev
qui va peupler statiquement et dynamiquement /dev
et
configure l’interface réseau loopback.
Enfin, le fichier etc/fstab
liste les systèmes de
fichiers à monter au démarrage.
cpio
$ cd ..
$ find . | cpio -o -H newc -R +0:+0 | gzip > initramfs.gz
Puis, si vous êtes en salle de TP, quittez l’environnement
fakeroot
:
$ exit
$ cd ..
$ ./qemu-system-arm -machine vexpress-a9 -nographic -kernel \
\
linux-5.15.6/build/arch/arm/boot/zImage \
-dtb linux-5.15.6/build/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -initrd initramfs_busybox/initramfs.gz
Une fois Linux démarré, il suffit d’appuyer sur une touche pour accéder à un interpréteur de commande.
Le dernier élément dont nous aurions besoin sur un système réel est un bootloader (comme nous l’avons vu, QEMU sait faire démarrer le noyau Linux correctement et a donc fait office jusqu’ici de bootloader).
Nous allons utiliser Das U-Boot qui est l’un des bootloaders les plus utilisés dans le monde de l’embarqué avec Linux.
$ cd $TPROOT
$ wget https://ftp.denx.de/pub/u-boot/u-boot-2020.10.tar.bz2
$ tar xjf u-boot-2020.10.tar.bz2
$ cd u-boot-2020.10
$ make distclean
$ export ARCH=arm
$ export CROSS_COMPILE=arm-linux-gnueabihf-
$ make vexpress_ca9x4_defconfig
$ make
$ cd ..
$ ./qemu-system-arm -machine vexpress-a9 -nographic -kernel u-boot-2020.10/u-boot
Pensez à appuyer sur une touche pendant le compte-à-rebours d’U-Boot. À défaut, il va essayer de trouver une image de Linux à charger depuis les périphériques qu’il supporte (carte SD, mémoire flash, réseau). Comme aucun de ces périphériques émulés ne contient le noyau, le processus de démarrage va échouer.
Cette section n’est pas réalisable sur les machines des salles de TP, vous pouvez vous contentez de la lire.
Dans un système réel, le bootloader (U-Boot) serait stocké très probablement sur une carte SD ou dans une mémoire flash du système et serait mis en mémoire et lancé par un preloader (cette partie est très dépendante d’un système à un autre). Dans le cadre de ce TP, ce preloader est simulé par QEMU qui place l’image d’U-Boot en mémoire et lance son exécution.
Ensuite, dans un système réel, U-Boot irait chercher l’image du noyau
Linux, le système de fichiers mémoire initial (initramfs
ou
initrd
) et l’arbre des périphériques depuis un périphérique
(le plus souvent carte SD ou mémoire flash interne, mais cela peut
également être le réseau via TFTP par exemple) et les placerait en
mémoire.
Nous allons simuler cette situation en générant une image de carte SD contenant ces éléments et en demandant à QEMU de l’utiliser pour que U-Boot puisse charger les éléments qu’elle contient.
ATTENTION : Faites très attention en utilisant les commandes suivantes (parted, mkfs, etc., surtout lorsqu’elles sont précédées de sudo). Vous pourriez vous retrouver à écraser vos données si vous ne faites pas attention aux arguments que vous passez à ces commandes.
sdcard
qui contiendra l’image de cette
carte SD$ cd $TPROOT
$ mkdir sdcard
$ cd sdcard
$ dd if=/dev/zero of=sd bs=1M count=64
$ parted sd
(parted) mklabel msdos
(parted) mkpart primary fat32 1MiB 100%
(parted) print
Modèle : (file)
Disque : 67,1MB
Taille des secteurs (logiques/physiques) : 512B/512B
Table de partitions : msdos
Drapeaux de disque :
Numéro Début Fin Taille Type Système de fichiers Drapeaux
1 1049kB 67,1MB 66,1MB primary fat32 lba
(parted) quit
losetup
faites apparaître cette partition comme
un périphérique dans /dev
$ sudo losetup -f --show -P sd
/dev/loop0
(si la commande renvoie un autre numéro que loop0
,
modifiez les lignes suivantes)
$ sudo mkfs.fat -F 32 /dev/loop0p1
$ mkdir mnt
$ sudo mount /dev/loop0p1 mnt
initramfs
$ sudo cp ../linux-5.15.6/build/arch/arm/boot/zImage mnt
$ sudo cp ../linux-5.15.6/build/arch/arm/boot/dts/vexpress-v2p-ca9.dtb mnt
$ sudo cp ../initramfs_busybox/initramfs.gz mnt
$ cd mnt
$ sudo ../../u-boot-2020.10/tools/mkimage -A arm -O linux -T ramdisk -d initramfs.gz uinitramfs
$ cd ..
$ sudo umount mnt
$ sudo losetup -d /dev/loop0
$ cd $TPROOT
$ qemu-system-arm -machine vexpress-a9 -nographic -kernel \
-sd sdcard/sd u-boot-2020.10/u-boot
=> fatload mmc 0:1 0x62000000 zImage
=> fatload mmc 0:1 0x63000000 vexpress-v2p-ca9.dtb
=> fatload mmc 0:1 0x63100000 uinitramfs
=> bootz 0x62000000 0x63100000 0x63000000
Et voilà !
Dans un système réel, ces commandes pourraient être automatisées pour être exécutées automatiquement. Cette automatisation peut se faire en dur lors de la compilation d’U-Boot.
© Copyright 2020 Guillaume Duc. Le contenu de cette page est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International (à l'exception des exemples de code tirés du noyau Linux et qui sont distribués sous leurs licences d'origine).