|
M2 SETI B4 / MS SE SE758 |
L’objectif de ce TP est de compiler et charger votre premier module noyau.
Nous allons reprendre le répertoire créé lors du précédent TP.
$ export TPROOT=xxx
$ cd $TPROOTPensez à adapter les commandes ci-dessus en fonction du nom donné au
répertoire lors du premier TP (remplaçez xxx par
/home/users/xxx/seti-b4-tp par exemple si vous êtes sur les
machines de l’école).
Par rapport aux deux TP précédents, vous devez conserver :
arm-linux-gnueabihf de Linaro
que vous aviez téléchargée lors du premier TP.Profitez-en pour vérifier qu’elle est toujours dans votre
PATH en tapant :
$ arm-linux-gnueabihf-gcc --versionVérifiez que le résultat de cette commande est :
arm-linux-gnueabihf-gcc (Linaro GCC 7.4-2019.02) 7.4.1 20181213 [linaro-7.4-2019.02 revision 56ec6f6b99cc167ff0c2f8e1a2eed33b1edc85d4]
qemu que vous aviez téléchargée
lors du premier TP.Vous pouvez supprimer le reste afin de libérer de la place si besoin.
Pour ce TP, ainsi que les suivants, vous aurez besoin de récupérer :
Déplacez ces trois composants dans votre répertoire
$TPROOT et décompressez l’archive contenant le noyau :
$ tar xJf linux_build.tar.xzVous pouvez supprimer l’archive une fois décompressée afin de gagner de la place :
$ rm linux_build.tar.xzVérifiez que le noyau et l’image fournie démarrent correctement :
$ cd $TPROOT
$ ./qemu-system-arm -nographic -machine vexpress-a9 -kernel linux-5.10.19/build/arch/arm/boot/zImage \
-dtb linux-5.10.19/build/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -initrd rootfs.cpio.gzVous devriez voir sur la console le démarrage de Linux puis un écran
de login. Vous pouvez vous connecter en tant que root (sans
mot de passe).
Rappel : pour quitter QEMU, faites ctrl-a c, puis
quit.
Voici le code de votre premier module.
/* first.c */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int __init first_init(void)
{
pr_info("Hello world!\n");
return 0;
}
static void __exit first_exit(void)
{
pr_info("Bye\n");
}
module_init(first_init);
module_exit(first_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("My first module");
MODULE_AUTHOR("Me");Ce module ne fait pas grand chose, à l’exception d’afficher un message lors de son chargement et un autre lors de son déchargement.
Voici le fichier Makefile nécessaire pour compiler le
module :
ifneq ($(KERNELRELEASE),)
# kbuild part of makefile
obj-m := first.o
else
# normal makefile
KDIR ?= /lib/modules/`uname -r`/build
default:
$(MAKE) -C $(KDIR) M=$$PWD
endifAttention ! La ligne $(MAKE) -C... qui
indique la commande à exécuter pour construire la cible
default doit être indentée à l’aide d’une tabulation et non
d’un ou plusieurs espaces.
Ce Makefile est très bien adapté à la compilation d’un
module depuis la machine sur lequel vous voulez l’utiliser (compilation
native). Nous verrons par la suite comment l’utiliser dans le contexte
de la compilation croisée (cross-compilation).
Plusieurs outils vous permettent de manipuler les modules :
modinfo <nom_module|module.ko> permet d’obtenir
les informations sur un module (auteur, description, licence
d’utilisation, version du noyau pour laquelle il a été compilé, liste
des paramètres acceptés, etc.)insmod <module.ko> permet de charger un
modulemodprobe <nom_module> permet de charger un module
et ses dépendances éventuelleslsmod permet de lister les modules actuellement
chargésrmmod <nom_module> permet de décharger un module.
Cette opération n’est possible que si le module n’est pas en cours
d’utilisationmodprobe -r <nom_module> permet également de
décharger un module et toutes ses dépendances si elles ne sont pas
utiliséesCréez un répertoire de travail pour votre premier module :
$ cd $TPROOT
$ mkdir premier_module
$ cd premier_moduleCopiez le module ci-dessus ainsi que le
Makefile
Compilez votre module
$ make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm KDIR=../linux-5.10.19/build/La variable CROSS_COMPILE indique le préfixe des outils
de la chaîne de compilation que nous utilisons (donc le gcc
qui sera appelé est arm-linux-gnueabihf-gcc). La variable
ARCH indique que nous compilons pour l’architecture
arm. Enfin KDIR pointe vers le répertoire dans
lequel le noyau a été compilé (en effet, bien que vous compilez le code
de votre module à l’extérieur de l’arbre des sources du noyau, le
mécanisme de compilation a besoin notamment des fichiers d’entêtes du
noyau).
Votre module est maintenant dans le fichier
first.ko.
Démarrez QEMU :
$ cd ..
$ ./qemu-system-arm -nographic -machine vexpress-a9 -kernel linux-5.10.19/build/arch/arm/boot/zImage \
-dtb linux-5.10.19/build/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -initrd rootfs.cpio.gz \
-fsdev local,path=premier_module,security_model=mapped,id=mnt -device virtio-9p-device,fsdev=mnt,mount_tag=mntVoici quelques explications sur les différents arguments passés à QEMU :
-machine vexpress-a9 : indique le type de machine à
simuler (ici une carte Arm Versatile Express munie d’une carte
d’extension CoreTile Express A9x4)-kernel linux-5.10.19/build/arch/arm/boot/zImage :
indique l’image du noyau Linux à charger au démarrage-dtb linux-5.10.19/build/arch/arm/boot/dts/vexpress-v2p-ca9.dtb
: indique le fichier contenant l’arbre des périphériques à charger au
démarrage-initrd rootfs.cpio.gz : indique l’image du système de
fichiers racine à charger en mémoire (ici une image
initramfs)-fsdev local,path=premier_module,security_model=mapped,id=mnt -device virtio-9p-device,fsdev=mnt,mount_tag=mnt
permet de partager le contenu du répertoire premier_module
entre votre machine et la machine émulée par QEMUAprès vous être loggué en tant que root, montez le
partage avec la machine hôte en tapant, dans la console émulée par QEMU
:
$ mount -t 9p -o trans=virtio mnt /mnt -oversion=9p2000.L,msize=10240Si cette commande s’exécute correctement, vous aurez alors accès,
dans le répertoire /mnt de la machine émulée par QEMU, au
contenu du répertoire premier_module de votre machine (et
donc au module que vous venez de compiler).
Chargez votre module (depuis QEMU) :
$ insmod /mnt/first.koDéchargez votre module
$ rmmod firstFélicitations, vous avez écrit votre premier module pour le noyau.
© 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).