Programovanie modulov Linuxového jadra: Program Hello World
Moduly jadra sú časti kódu, ktoré možno na požiadanie načítať a uvoľniť do jadra. Rozširujú funkčnosť jadra bez potreby reštartu systému. Vlastné kódy je možné pridať do linuxových jadier dvoma spôsobmi.
- Základným spôsobom je pridať kód do zdrojového stromu jadra a prekompilovať jadro.
- Efektívnejším spôsobom je pridať kód do jadra počas jeho spustenia. Tento proces sa nazýva načítanie modulu, kde modul odkazuje na kód, ktorý chceme pridať do jadra.
- ovládač zariadenia
- ovládač súborového systému a
- Systémové volania.
/** * @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 );
Vysvetlenie vyššie uvedeného kódu: Moduly jadra musia mať aspoň dve funkcie: funkciu „štart“ (inicializáciu) nazývanú init_module(), ktorá sa volá, keď je modul vložený do jadra, a funkciu „konca“ (vyčistenie) nazývanú cleanup_module(), ktorá sa volá tesne pred tým, ako je modul rmmoded. V skutočnosti sa veci zmenili počnúc jadrom 2.3.13. Teraz môžete použiť ľubovoľný názov pre počiatočné a koncové funkcie modulu. V skutočnosti je nová metóda preferovanou metódou. Mnoho ľudí však stále používa init_module() a cleanup_module() pre svoje počiatočné a koncové funkcie. V tomto kóde sme použili hello_start() ako funkciu init a hello_end() ako funkciu čistenia. Ďalšia vec, ktorú ste si mohli všimnúť, je, že namiesto funkcie printf() sme použili printk(). Je to preto, že modul nevytlačí nič na konzole, ale zaznamená správu do /var/log/kern.log. Preto sa používa na ladenie modulov jadra. Okrem toho je v hlavičke definovaných osem možných reťazcov loglevel, ktoré sa vyžadujú pri použití printk(). Uvádzame ich v poradí podľa klesajúcej závažnosti: - KERN_EMERG: Používa sa pre núdzové správy, ktoré zvyčajne predchádzajú havárii.
- KERN_ALERT: Situácia vyžadujúca okamžitú akciu.
- KERN_CRIT: Kritické stavy často súvisia s vážnymi poruchami hardvéru alebo softvéru.
- KERN_ERR: Používa sa na hlásenie chybových stavov; ovládače zariadení často používajú KERN_ERR na hlásenie problémov s hardvérom.
- KERN_WARNING: Upozornenia na problematické situácie, ktoré samy osebe nespôsobujú vážne problémy so systémom.
- KERN_NOTICE: Situácie, ktoré sú normálne, ale stále stoja za zmienku. Na tejto úrovni sa uvádza množstvo podmienok súvisiacich s bezpečnosťou.
- KERN_INFO: Informačné správy. Mnoho ovládačov tlačí informácie o hardvéri, ktorý nájdu pri spustení na tejto úrovni.
- KERN_DEBUG: Používa sa na ladenie správ. Na tlač správy sme použili KERN_INFO. Príprava systému na spustenie kódu: 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 na kompiláciu zdrojového kódu:
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**Poznámka: Nezabudnite na medzery tabulátorov v Makefile Kompilácia a načítanie modulu: 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.koTestovanie modulu: 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.