Modules
Introduction
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).
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 ainsi 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 à la compilation
La compilation nécessite un ensemble d’outils tels que le compilateur gcc, l’utilitaire make...
a. Debian
Vous devez installer les paquets gcc, build-essential et les fichiers d’en-têtes (headers) du noyau :
root@system1:~# apt-get install gcc build-essential
linux-headers-$(uname -r)
b. Red Hat
Installez les outils de développement :
[root@system2 ~]# yum group install "Development tools"
Installez aussi le paquet de développement du noyau qui correspond à la version de votre noyau. Utilisez la commande uname que nous avons vue dans le chapitre Architecture du système GNU/Linux pour l’identifier.
[root@system2 ~]# yum install kernel-devel-3.10.0-862.14.4.el7.x86_64
Modules complémentaires chargés : fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: centos.mirror.fr.planethoster.net
* extras: centos.mirror.fr.planethoster.net
* updates: centos.mirror.fr.planethoster.net
Résolution des dépendances
--> Lancement de la transaction de test
---> Le paquet kernel-devel.x86_64 0:3.10.0-862.14.4.el7 sera installé
--> Résolution des dépendances terminée
Dépendances résolues
=======================================================================
Package Architecture Version Dépôt Taille
=======================================================================
Installation :
kernel-devel ...
Charger un module
Le chargement d’un module s’effectue avec les commandes insmod ou modprobe. Mais commençons par l’installer.
1. Installer le module hello
Exécutez make install :
[root@system2 ~]# make install
cp ./hello.ko* /lib/modules/3.10.0-862.14.4.el7.x86_64/kernel/drivers/misc
Le fichier hello.ko ou hello.ko.xz est alors copié dans le dossier /lib/modules/$(uname -r)/kernel/drivers/misc :
[root@system2 ~]# ls /lib/modules/$(uname -r)/kernel/drivers/misc/hello*
/lib/modules/3.10.0-862.14.4.el7.x86_64/kernel/drivers/misc/hello.ko.xz
2. insmod
La commande insmod accepte n’importe quel emplacement du module, lequel n’a pas besoin de résider dans le répertoire /lib/modules/$(uname-r). Cependant, les dépendances ne sont pas chargées automatiquement.
Utilisé par modprobe, c’est un programme de bas niveau pour charger les modules.
Syntaxe
insmod <nom_du_module_à_charger>
Charger le module hello.ko.xz
[root@system2 ~]# insmod /lib/modules/$(uname -r)/kernel/drivers/
misc/hello.ko.xz
3. Gérer les dépendances
Le fichier modules.dep contient la liste des dépendances de chargement de chaque module qui est utilisé par modprobe.
Utilisez la commande depmod lorsqu’un changement sur les modules survient pour s’assurer que toutes les dépendances soient chargées. Elle reconstruit le fichier...
Décharger un module
rmmod décharge un module du noyau si aucun processus ne l’utilise. Si c’était le cas, ajoutez le commutateur -w (ou --wait). Ainsi, le processus est isolé en attendant qu’il ne soit plus utilisé puis il sera déchargé.
Syntaxe
rmmod <option> <nom_du_module_à_décharger>
Options utiles :
Option |
Description |
|
courte |
longue |
|
-f |
--force |
Force le déchargement du module. |
-w |
--wait |
Isole le module et attend que le module ne soit plus utilisé. |
modprobe peut décharger un module de la même façon que rmmod.
Syntaxe
modprobe <options> <nom_du_module_à_décharger>
Options nécessaires :
Option |
Description |
|
courte |
longue |
|
-r |
--remove |
Décharge le module mentionné. |
-v |
--verbose |
Mode verbeux. |
Décharger le module hello
[root@system2 ~]# rmmod hello
ou bien :
[root@system2 ~]# modprobe -rv hello
rmmod hello
Vérifiez avec lsmod et grep que le module est bien déchargé :
[root@system2 ~]# lsmod |grep hello
Consultez le journal /var/log/messages pour Debian et CentOS :
[root@system2 ~]# cat /var/log/messages
*** sortie tronquée ***
Nov 20 22:08:49 system2 nm-dispatcher: req:1 'dhcp4-change'
[enp0s8]: start running ordered scripts...
Nov 20 22:09:05 system2 kernel: [Hello world] - La fonction
cleanup_module()...
Lister les modules
1. Lister tous les modules disponibles
Pour répertorier les modules disponibles, le commutateur -l de la commande modprobe, n’existe plus.
Il faut alors parcourir avec find le dossier /lib/modules/$(uname -r) et répertorier les fichiers dont l’extension est .ko. awk va permettre d’afficher uniquement le nom du fichier :
[root@system2 ~]# find /lib/modules/$(uname -r) -name '*.ko*' |
awk -F "/" '{print $NF}' | sort
3w-9xxx.ko.xz
3w-sas.ko.xz
6lowpan.ko.xz
8021q.ko.xz
8139cp.ko.xz
8139too.ko.xz
a8293.ko.xz
aacraid.ko.xz
abituguru3.ko.xz
abituguru.ko.xz
ablk_helper.ko.xz
ac97_bus.ko.xz
acard-ahci.ko.xz
acecad.ko.xz
*** sortie tronquée ***
2. Lister les modules chargés
lsmod affiche des modules chargés. Les informations sont issues du fichier /proc/modules :
[root@system2 ~]# lsmod
hello 12426 0
binfmt_misc 17468 1
nls_utf8 12557 1
isofs 39844 1
ip6t_rpfilter 12595 1
ipt_REJECT 12541 ...
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.
Syntaxe
modinfo <nom_du_module>
Les informations du module ext3
Vous constatez, par la même occasion, que ext3 est en fait un alias de ext4.
[root@system2 ~]# modinfo ext3
filename: /lib/modules/3.10.0-862.14.4.el7.x86_64/kernel/fs/ext4/
ext4.ko.xz
license: GPL
description: Fourth Extended Filesystem
author: Remy Card, Stephen Tweedie, Andrew Morton,
Andreas Dilger, Theodore Ts'o and others
alias: fs-ext4
alias: ext3
alias: fs-ext3
alias: ext2
alias: fs-ext2
retpoline: Y
rhelversion: 7.5
srcversion: 8BDF72C8A0EF1E5EA5D28E7
depends: mbcache,jbd2
intree: Y
vermagic: 3.10.0-862.14.4.el7.x86_64 SMP mod_unload modversions
signer: CentOS Linux kernel signing key
sig_key: E4:A1:B6:8F:46:8A:CA:5C:22:84:50:53:18:FD:9D:AD:72:4B:13:03
sig_hashalgo: sha256
Les dépendances peuvent être affichées également avec modprobe.
Syntaxe...
Bloquer un module
Pour des soucis de stabilité, de compatibilité avec d’autres programmes ou pour toute autre raison, un module peut être bloqué ou « blacklisté ».
Vous avez la possibilité de créer votre propre fichier pour bloquer les modules que vous souhaitez dans le dossier /etc/modprobe.d. Il est conseillé de le nommer de façon explicite et il doit porter l’extension .conf.
Le dossier /etc/modprobe.d n’a pas le même contenu par défaut d’une distribution à l’autre. Le contenu de celui-ci dans Debian 9 est vide contrairement à RHEL 7 :
[root@system2 ~]# ls -1 /etc/modprobe.d/
dccp-blacklist.conf
firewalld-sysctls.conf
tuned.conf
La syntaxe de ce dernier est blacklist <nom-du-pilote> comme par exemple : blacklist dccp.
Bloquer le module hello
Créez un fichier blacklist-hello.conf dans le dossier /etc/modprobe.d/ :
# Bloquer le module de noyau hello
blacklist hello
Journaux système
Lorsque le système d’exploitation est amorcé, le noyau Linux est chargé en mémoire. Chaque pilote de périphérique chargé fait une tentative de détection du matériel concerné. Si l’opération est réussie alors un message de diagnostic détaille ce qu’il a trouvé.
Vous pouvez consulter, par l’intermédiaire de la commande journalctl qui remplace dmesg les messages du buffer (mémoire tampon) du noyau.
Syntaxe
journalctl <option>
Option :
Option |
Description |
|
courte |
longue |
|
-k |
--desmg |
Afficher uniquement les messages du noyau. |
Exemple
[root@system2 ~]# journalctl -k
-- Logs begin at mar. 2018-11-20 18:52:41 CET, end at
mar. 2018-11-20 23:20:01 CET. -
nov. 20 18:52:41 system2.staff.local kernel: Initializing
cgroup subsys cpuset
nov. 20 18:52:41 system2.staff.local kernel: Initializing
cgroup subsys cpu
nov. 20 18:52:41 system2.staff.local kernel: Initializing
cgroup subsys cpuacct
*** sortie tronquée ***
Il est à noter que la commande dmesg et son fichier /var/log/dmesg sont encore présents pour assurer la compatibilité antérieure. Ils pourraient bien disparaître dans la version RHEL 8.
Recherche d’informations sur une carte réseau Intel
[root@system2 ~]# journalctl -k |grep e1000
nov. 20 18:52:41 system2.staff.local kernel:...
Exercice
1. Créez un répertoire LKM dans votre répertoire de base et entrez dans celui-ci.
2. Écrivez le code suivant :
#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");
}
3. Écrivez le fichier 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
4. Compilez puis installez.
5. Chargez le module automatiquement au démarrage du système.
6. Vérifiez le chargement après...