Concept de module
Introduction
La fonctionnalité du noyau Linux peut en tout temps être adaptée, modifiée ou étendue
Des applications nécessitant un accès au matériel ou devant traiter une très grande quantité d’information en provenance d’interfaces réseau (piles de protocoles) seront assez naturellement conçues pour fonctionner dans l’espace noyau en collaboration avec les threads du noyau Linux. Dans ce cas on parle de modules noyau ou d’objets noyau (kernel objects).
Linux propose deux techniques pour lier ces modules avec le noyau
- Statique
- Le module est compilé et linké statiquement avec l’image du noyau
- Le module est chargé avec le noyau lors du démarrage
- Dynamique
- Le module est compilé séparément du noyau, mais en utilisant la version courante du noyau (current running kernel)
- Le module est chargé par des applications utilisateur en fonction des besoins
- Ces modules/objets noyau ont l’extension
*.ko
Avantages des modules noyaux
Il existe de nombreux avantages à développer des modules noyaux
- Développement plus aisé et plus rapide : Pas nécessaire de redémarrer le noyau Linux après une modification du module, les modules peuvent être chargés, testés, déchargés, régénérés
- Maîtrise de la taille du noyau Linux : En ne chargeant que les modules utiles, on peut plus facilement garder la taille de l’image du noyau Linux au minimum
- Chargement de pilotes de périphériques que si le système les reconnaît : Si le système ne connaît pas quels périphériques sont attachés au système avant son démarrage ou si les périphériques ne sont pas systématiquement utilisés par les applications, alors ceux-ci ne seront pas chargés dans le noyau Linux
- Diminution du temps de démarrage des cibles : Aucun temps n’est perdu à initialiser des périphériques ou des fonctions du noyau si elles ne sont pas utilisées
- Pas de modification des sources de la distribution : Ils ne nécessitent pas (en principe) de modification des sources du noyau Linux et de son dépôt (git repository) car les modules peuvent être développés à l’extérieur de l’arborescence du noyau Linux
Limitations des modules noyaux
Le développement de module sous Linux souffre de quelques limitations:
- Le module doit impérativement être développé en C (ou récemment en Rust). C++ n’est pas supporté (voir http://vger.kernel.org/lkml/#s15-3).
- Le module doit impérativement être développé sous licence en général GPL (GNU Public Licence)
- La bibliothèque standard C n’est pas disponible dans le noyau.
D’autres méthodes doivent être utilisées. Les fichiers propres
au noyau sont placés dans le répertoire
<linux/>
- L’usage des nombres en virgule flottante n’est pas supporté si le microprocesseur ne dispose pas d’un coprocesseur mathématique
- Le débogage des modules est nettement plus complexe
Attention
- Une fois chargé dans le noyau, le module a plein contrôle sur l’ensemble du système avec tous les privilèges
- Une erreur de programmation dans un module peut causer le crash de tout le système
Squelette d’un module
// skeleton.c
#include <linux/module.h> // needed by all modules
#include <linux/init.h> // needed for macros
#include <linux/kernel.h> // needed for debugging
static int __init skeleton_init(void)
{
pr_info ("Linux module skeleton loaded\n");
return 0;
}
static void __exit skeleton_exit(void)
{
pr_info ("Linux module skeleton unloaded\n");
}
module_init (skeleton_init);
module_exit (skeleton_exit);
MODULE_AUTHOR ("Jacques Supcik <jacques.supcik@hefr.ch>");
MODULE_DESCRIPTION ("Module skeleton");
MODULE_LICENSE ("GPL");
Explications du module
Initialisation
- La fonction
skeleton_init
est appelée lorsque le module est chargé dans le noyau. Elle retourne un code d’erreur (0
pour succès, une valeur négative, par exemple:EACCES
, en cas d’erreur). Liste des codes d’erreurs:Elle est éliminée après l’initialisation du module (macro#include <linux/errno.h>
__init
). - La macro
module_init
permet de déclarer le nom de la fonction d’initialisation.
Nettoyage
- La fonction
skeleton_exit
est appelée lorsque le module est désinstallé. Si le module est compilé statiquement avec le noyau, la fonction est écartée (macro__exit
). - La macro
module_exit
permet de déclarer le nom de la fonction d’initialisation.
Métadonnées
- Les macros
MODULE_AUTHOR
,MODULE_DESCRIPTION
etMODULE_LICENSE
permettent de déclarer des informations sur le module et le type de licence utilisé (généralement GPL).