Introduction
Vous avez déjà eu une présentation
des modules dans le chapitre Architecture du système GNU/Linux.
Refaisons le point.
Un module ou Loadable Kernel Module (LKM)
en anglais est un morceau de code qui peut être chargé et
déchargé dans le noyau Linux sur demande. Il apporte à ce
dernier une fonctionnalité telle qu’un pilote de périphérique,
un pare-feu (firewall), un protocole réseau, etc.
Les modules s’exécutent en mode kernel
(anneau 0) et non dans le mode utilisateur (anneau 3).
Le fait de créer une fonctionnalité en
tant que module au lieu de l’intégrer au sein du noyau évite
d’alourdir celui-ci. Il n’est pas nécessaire d’inclure
dans le noyau du code que l’on n’utilise pas souvent voire jamais.
Des tiers peuvent aussi développer
des modules qui sont fournis à part. L’administrateur peut
les installer et ensuite les charger sans qu’il soit nécessaire de
recompiler le noyau.
Compiler et installer un module
Un module est compilé pour une version
précise du noyau Linux.
Si, durant la mise à jour de votre
système, une nouvelle version du noyau est installée
alors tous les modules fournis par la distribution seront compilés
de nouveau. Par contre, les modules que vous avez ajoutés
personnellement ne seront pas recompilés. Vous devrez les
recompiler manuellement.
1. Pré-requis pour compiler
La compilation nécessite un ensemble
d’outils tel que le compilateur gcc (The GNU Compiler Collection), l’utilitaire make...
a. Debian et Ubuntu
Vous devez installer les paquets gcc, build-essential et
les fichiers d’en-têtes (headers) du noyau :
# apt-get install gcc build-essential linux-headers-$(uname -r)
b. Red Hat
Installez les outils de développement :
# yum groupinstall "Development tools"
2. Écrire un module « Hello world »
Pour comprendre la mise en place d’un LKM,
vous allez concevoir en langage C un module simple et traditionnel
dans le monde du développement : « hello world ».
Le but de ce dernier est d’envoyer un message
dans le journal système /var/log/syslog pendant
son chargement ou son déchargement.
a. Rédiger le code source
À l’aide d’un éditeur de
texte tel que vi ou nano, créez le fichier hello.c :
#include <linux/module.h> #include <linux/kernel.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("John Doe"); MODULE_DESCRIPTION("Module hello world"); MODULE_VERSION("Version 1.00"); int init_module(void) { printk(KERN_INFO "[Hello world] - La fonction init_module() est appelée.\n"); return 0; } void cleanup_module(void) { printk(KERN_INFO "[Hello world] - La fonction cleanup_module() est appelée.\n"); }
Les deux premières lignes du code
source incluent deux fichiers d’en-têtes :
-
module.h nécessaire pour tous les modules,
-
kernel.h pour la définition des macros comme KERN_INFO.
Les macros MODULE_LICENSE, MODULE_AUTHOR, MODULE_DESCRIPTION et MODULE_VERSION définissent
des informations sur le module.
int init_module(void) et void cleanup_module(void) sont deux
fonctions nécessaires puisque la première s’exécute
lors du chargement et la seconde pendant le déchargement
du module.
La fonction printk() affiche
les messages dans le journal du noyau. Du fait que nous sommes dans
un bas niveau (espace noyau), nous ne pouvons pas utiliser la fonction printf() définie dans le
fichier stdio.h qui affiche une chaîne
de caractères à l’écran. Cette dernière
est utilisable dans l’espace utilisateur.
b. Créer le fichier Makefile
Le fichier Makefile contient
les instructions utilisées par make pendant
la construction d’un exécutable, d’une bibliothèque
ou bien d’un module.
Tapez les lignes suivantes dans un éditeur
de texte et enregistrez le fichier sous le nom de Makefile :
obj-m += hello.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean install: cp ./hello.ko /lib/modules/$(shell uname -r)/kernel/drivers/misc
obj-m (object module) signifie qu’il existe un objet nommé hello.o qui sera construit à partir
de hello.c.
Ensuite, Makefile contient
trois cibles :
-
all:
-
clean:
-
install:
La cible all: construit
le module. Si vous tapez uniquement make,
la première cible du fichier Makefile sera
appliquée en l’occurrence all:.
C’est identique à make all.
La cible clean: nettoie
les fichiers de construction d’une précédente
compilation. Par exemple, si une compilation effectuée
avec make se termine par un échec.
Vous corrigez les erreurs rencontrées. Avant de relancer
la commande make, vous devez nettoyer
les fichiers de la précédente compilation en invoquant make clean.
Si vous exécutez make
install, la cible install: installe
l’exécutable dans les répertoires spécifiés.
c. Compiler le code source hello.c
Tapez make pour
construire le module :
# make make -C /lib/modules/2.6.32-5-amd64/build M=/home/bob modules make[1]: entrant dans le répertoire «/usr/src/linux-headers- 2.6.32-5-amd64» CC [M] /home/bob/hello.o Building modules, stage 2. MODPOST 1 modules CC /home/bob/hello.mod.o LD [M] /home/bob/hello.ko make[1]: quittant le répertoire « /usr/src/linux-headers-2.6.32-5- amd64 »
La construction a créé plusieurs
fichiers car celle-ci se réalise en différentes étapes.
Le fichier module proprement dit est hello.ko :
# ls hello.c hello.mod.c hello.o Makefile modules.order hello.ko hello.mod.o Module.symvers
Obtenir des informations
Modinfo affiche
les informations d’un module telles que le nom du fichier et son
emplacement, sa licence, une description, le ou les auteurs, les
dépendances et sa version.
Syntaxemodinfo <nom_du_module>Les informations du module ext3
# modinfo ext3 filename: /lib/modules/2.6.32-5-amd64/kernel/fs/ext3/ext3.ko license: GPL description: Second Extended Filesystem with journaling extensions author: Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts’o and others depends: mbcache,jbd vermagic: 2.6.32-5-amd64 SMP mod_unload modversions
Les dépendances peuvent être
affichées également avec modprobe.
Syntaxemodprobe <option> <nom_du_module>
Option :
Option longue
|
Description
|
--show-depends
|
Liste les dépendances d’un module.
|
# modprobe --show-depends ext4 insmod /lib/modules/3.10.2-20130726/kernel/fs/mbcache.ko insmod /lib/modules/3.10.2-20130726/kernel/fs/jbd2/jbd2.ko insmod /lib/modules/3.10.2-20130726/kernel/lib/crc16.ko insmod /lib/modules/3.10.2-20130726/kernel/fs/ext4/ext4.koou encore avec lsmod :
# lsmod |grep ext4 ext4 377227 3 crc16 12343 2 ext4,bluetooth mbcache 13082 1 ext4 jbd2 76198 1 ext4
Vous pouvez organiser l’affichage des informations
des modules : nom du module et emplacement, description
et dépendances en utilisant des commandes avancées
du shell. Par exemple :
-
cut affiche des zones spécifiques d’un fichier texte. -d définit le séparateur de champ et -f1 extrait le premier champ.
-
sed (Stream Editor) permet de manipuler du texte.
-
egrep (ou grep -E) affiche les lignes correspondant à un motif.
-
Les expressions rationnelles et les expressions rationnelles étendues...
# modinfo $(cut -d’ ’ -f1 /proc/modules) | sed ’/ˆdep/s/$/\n/; /ˆfile\|ˆdesc\|ˆdep/!d’ filename: /lib/modules/2.6.32-5-amd64/kernel/drivers/misc/hello.ko description: Un exemple de LKM depends: filename: /lib/modules/2.6.32-5-amd64/kernel/drivers/cpufreq/ cpufreq_powersave.ko description: CPUfreq policy governor ’powersave’ depends: ... filename: /lib/modules/2.6.32-5-amd64/kernel/fs/ext3/ext3.ko description: Second Extended Filesystem with journaling extensions depends: mbcache,jbd filename: /lib/modules/2.6.32-5-amd64/kernel/fs/jbd/jbd.ko depends: filename: /lib/modules/2.6.32-5-amd64/kernel/fs/mbcache.ko description: Meta block cache (for extended attributes) depends: ...Deuxième exemple
# lsmod | cut -d’ ’ -f1 | xargs modinfo | egrep ’ˆfile|ˆdesc|ˆdep’ | sed -e’/ˆdep/s/$/\n/g’ filename: /lib/modules/2.6.32-5-amd64/kernel/drivers/misc/hello.ko description: Un exemple de LKM depends: filename: /lib/modules/2.6.32-5-amd64/kernel/drivers/cpufreq/ cpufreq_powersave.ko description: CPUfreq policy governor ’powersave’ depends: ...Troisième exemple
# find /lib/modules/$(uname -r) -name ’*.ko’ | xargs modinfo filename: /lib/modules/3.10.2- 20130726/kernel/net/bluetooth/rfcomm/rfcomm.ko alias: bt-proto-3 license: GPL version: 1.11 description: Bluetooth RFCOMM ver 1.11 author: Marcel Holtmann <marcel@holtmann.org> srcversion: 7D57E08D7FBF2D6B1E7BFA7 depends: bluetooth intree: Y vermagic: 3.10.2-20130726 SMP mod_unload modversions parm: disable_cfc:Disable credit based flow control (bool) parm: channel_mtu:Default MTU for the RFCOMM channel (int) parm: l2cap_mtu:Default MTU for the L2CAP connection (uint) parm: l2cap_ertm:Use L2CAP ERTM mode for connection (bool) filename: /lib/modules/3.10.2- 20130726/kernel/net/bluetooth/cmtp/cmtp.ko alias: bt-proto-5 license: GPL version: 1.0 description: Bluetooth CMTP ver 1.0 author: Marcel Holtmann <marcel@holtmann.org> srcversion: 8369758E5A8D8842F5E5A94 depends: kernelcapi,bluetooth intree: Y vermagic: 3.10.2-20130726 SMP mod_unload modversions ... filename: /lib/modules/3.10.2- 20130726/kernel/sound/synth/snd-util-mem.ko license: GPL description: Generic memory management routines for soundcard memory allocation author: Takashi Iwai depends: intree: Y vermagic: 3.10.2-20130726 SMP mod_unload modversions
Aucun commentaire :
Enregistrer un commentaire