Programació del mòdul del nucli de Linux: programa Hello World
Els mòduls del nucli són fragments de codi que es poden carregar i descarregar al nucli a petició. Amplien la funcionalitat del nucli sense necessitat de reiniciar el sistema. Els codis personalitzats es poden afegir als nuclis de Linux mitjançant dos mètodes.
- La manera bàsica és afegir el codi a l'arbre font del nucli i recompilar el nucli.
- Una manera més eficient de fer-ho és afegint codi al nucli mentre s'està executant. Aquest procés s'anomena carregar el mòdul on el mòdul fa referència al codi que volem afegir al nucli.
- controlador del dispositiu
- controlador del sistema de fitxers i
- Trucades del sistema.
/** * @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 );
Explicació del codi anterior: Els mòduls del nucli han de tenir almenys dues funcions: una funció d'inici (inicialització) anomenada init_module() que s'anomena quan el mòdul s'instal·la al nucli i una funció de finalització (neteja) anomenada cleanup_module() que es crida just abans de ser rmmoded. De fet, les coses han canviat a partir del nucli 2.3.13. Ara podeu utilitzar el nom que vulgueu per a les funcions d'inici i finalització d'un mòdul. De fet, el nou mètode és el mètode preferit. No obstant això, molta gent encara utilitza init_module() i cleanup_module() per a les seves funcions inicial i final. En aquest codi hem utilitzat hello_start() com a funció d'inici i hello_end() com a funció de neteja. Una altra cosa que potser haureu notat és que en comptes de la funció printf() hem utilitzat printk(). Això és perquè el mòdul no imprimirà res a la consola, però registrarà el missatge a /var/log/kern.log. Per tant, s'utilitza per depurar mòduls del nucli. A més, hi ha vuit possibles cadenes de nivell de registre definides a la capçalera que es requereixen quan s'utilitza printk(). Els hem enumerat per ordre decreixent de gravetat: - KERN_EMERG: s'utilitza per als missatges d'emergència generalment els que precedeixen un accident.
- KERN_ALERT: una situació que requereix una acció immediata.
- KERN_CRIT: condicions crítiques sovint relacionades amb errors greus de maquinari o programari.
- KERN_ERR: S'utilitza per informar de condicions d'error; Els controladors de dispositiu sovint utilitzen KERN_ERR per informar de problemes de maquinari.
- KERN_WARNING: Avisos sobre situacions problemàtiques que per si mateixes no creen problemes greus amb el sistema.
- KERN_NOTICE: Situacions normals però dignes de tenir en compte. En aquest nivell s'informa d'una sèrie de condicions relacionades amb la seguretat.
- KERN_INFO: Missatges informatius. Molts controladors imprimeixen informació sobre el maquinari que troben en el moment de l'inici en aquest nivell.
- KERN_DEBUG: S'utilitza per depurar missatges. Hem utilitzat KERN_INFO per imprimir el missatge. Preparant el sistema per executar el codi: 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 per compilar el codi font:
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**Nota: no oblideu els espais de pestanya a Makefile Compilació i càrrega del mòdul: 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.koProva el mòdul: 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.