Programmation du module du noyau Linux : programme Hello World
Les modules du noyau sont des morceaux de code qui peuvent être chargés et déchargés dans le noyau à la demande. Ils étendent les fonctionnalités du noyau sans qu'il soit nécessaire de redémarrer le système. Des codes personnalisés peuvent être ajoutés aux noyaux Linux via deux méthodes.
- La méthode de base consiste à ajouter le code à l’arborescence des sources du noyau et à recompiler le noyau.
- Un moyen plus efficace consiste à ajouter du code au noyau pendant son exécution. Ce processus est appelé chargement du module où module fait référence au code que nous voulons ajouter au noyau.
- pilote de périphérique
- pilote de système de fichiers et
- Appels système.
/** * @file hello.c * @author Akshat Sinha * @date 10 Sept 2016 * @version 0.1 * @brief An introductory 'Hello World!' loadable kernel * module (LKM) that can display a message in the /var/log/kern.log * file when the module is loaded and removed. The module can accept * an argument when it is loaded -- the name which appears in the * kernel log files. */ #include /* Needed by all modules */ #include /* Needed for KERN_INFO */ #include /* Needed for the macros */ /// < The license type -- this affects runtime behavior MODULE_LICENSE ( 'GPL' ); /// < The author -- visible when you use modinfo MODULE_AUTHOR ( 'Akshat Sinha' ); /// < The description -- see modinfo MODULE_DESCRIPTION ( 'A simple Hello world LKM!' ); /// < The version of the module MODULE_VERSION ( '0.1' ); static int __init hello_start ( void ) { printk ( KERN_INFO 'Loading hello module... n ' ); printk ( KERN_INFO 'Hello world n ' ); return 0 ; } static void __exit hello_end ( void ) { printk ( KERN_INFO 'Goodbye Mr. n ' ); } module_init ( hello_start ); module_exit ( hello_end );
Explication du code ci-dessus : Les modules du noyau doivent avoir au moins deux fonctions : une fonction de « démarrage » (initialisation) appelée init_module() qui est appelée lorsque le module est inséré dans le noyau et une fonction de « fin » (nettoyage) appelée cleanup_module() qui est appelée juste avant qu'il ne soit modifié. En fait, les choses ont changé depuis le noyau 2.3.13. Vous pouvez désormais utiliser le nom de votre choix pour les fonctions de début et de fin d'un module. En fait, la nouvelle méthode est la méthode préférée. Cependant, de nombreuses personnes utilisent encore init_module() et cleanup_module() pour leurs fonctions de début et de fin. Dans ce code, nous avons utilisé hello_start() comme fonction d'initialisation et hello_end() comme fonction de nettoyage. Une autre chose que vous avez peut-être remarquée est qu'au lieu de la fonction printf(), nous avons utilisé printk(). En effet, le module n'imprimera rien sur la console mais enregistrera le message dans /var/log/kern.log. Par conséquent, il est utilisé pour déboguer les modules du noyau. De plus, huit chaînes de niveau de journalisation possibles définies dans l'en-tête sont requises lors de l'utilisation de printk(). Nous les avons classés par ordre de gravité décroissante : - KERN_EMERG : utilisé pour les messages d'urgence, généralement ceux qui précèdent un crash.
- KERN_ALERT : une situation nécessitant une action immédiate.
- KERN_CRIT : conditions critiques souvent liées à de graves pannes matérielles ou logicielles.
- KERN_ERR : utilisé pour signaler les conditions d'erreur ; les pilotes de périphériques utilisent souvent KERN_ERR pour signaler des difficultés matérielles.
- KERN_WARNING : avertissements concernant des situations problématiques qui ne créent pas en elles-mêmes de graves problèmes avec le système.
- KERN_NOTICE : situations normales mais néanmoins dignes de mention. Un certain nombre de conditions liées à la sécurité sont signalées à ce niveau.
- KERN_INFO : messages d'information. De nombreux pilotes impriment des informations sur le matériel qu'ils trouvent au démarrage à ce niveau.
- KERN_DEBUG : utilisé pour le débogage des messages. Nous avons utilisé KERN_INFO pour imprimer le message. Préparation du système pour exécuter le code : The system must be prepared to build kernel code and to do this you must have the Linux headers installed on your device. On a typical Linux desktop machine you can use your package manager to locate the correct package to install. For example under 64-bit Debian you can use:
akshat@gfg:~$ sudo apt-get install build-essential linux-headers-$(uname -r)Makefile pour compiler le code source :
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**Remarque : n'oubliez pas les espaces de tabulation dans Makefile Compilation et chargement du module : Run the make command to compile the source code. Then use insmod to load the module.
akshat@gfg:~$ make make -C /lib/modules/4.2.0-42-generic/build/ M=/home/akshat/Documents/hello-module modules make[1]: Entering directory `/usr/src/linux-headers-4.2.0-42-generic' CC [M] /home/akshat/Documents/hello-module/hello.o Building modules stage 2. MODPOST 1 modules CC /home/akshat/Documents/hello-module/hello.mod.o LD [M] /home/akshat/Documents/hello-module/hello.ko make[1]: Leaving directory `/usr/src/linux-headers-4.2.0-42-generic'Now we will use insmod to load the hello.ko object.
akshat@gfg:~$ sudo insmod hello.koTest du module : You can get information about the module using the modinfo command which will identify the description author and any module parameters that are defined:
akshat@gfg:~$ modinfo hello.ko filename: /home/akshat/Documents/hello-module/hello.ko version: 0.1 description: A simple Hello world LKM author: Akshat Sinha license: GPL srcversion: 2F2B1B95DA1F08AC18B09BC depends: vermagic: 4.2.0-42-generic SMP mod_unload modversionsTo see the message we need to read the kern.log in /var/log directory.
akshat@gfg:~$ tail /var/log/kern.log ... ... Sep 10 17:43:39 akshat-gfg kernel: [26380.327886] Hello world To unload the module we run rmmod: akshat@gfg:~$ sudo rmmod hello Now run the tail command to get the exit message. akshat@gfg:~$ tail /var/log/kern.log ... Sep 10 17:43:39 akshat-gfg kernel: [26380.327886] Hello world Sep 10 17:45:42 akshat-gfg kernel: [26503.773982] Goodbye Mr.