Linux kernel modul programozás: Hello World Program
A kernelmodulok olyan kóddarabok, amelyek igény szerint betölthetők és kirakhatók a kernelbe. Kibővítik a kernel funkcionalitását a rendszer újraindítása nélkül. Egyéni kódok kétféle módon adhatók hozzá a Linux kernelekhez.
- Az alapvető módszer az, hogy hozzáadjuk a kódot a kernel forrásfához, és újrafordítjuk a kernelt.
- Ennek hatékonyabb módja, ha kódot adunk a kernelhez, miközben az fut. Ezt a folyamatot a modul betöltésének nevezzük, ahol a modul arra a kódra utal, amelyet hozzá szeretnénk adni a kernelhez.
- eszközillesztő
- fájlrendszer illesztőprogram és
- Rendszerhívások.
/** * @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 );
Magyarázat a fenti kódhoz: A kernelmoduloknak legalább két funkcióval kell rendelkezniük: az init_module() nevű 'start' (inicializálási) függvénynek, amely akkor hívódik meg, amikor a modult beépítik a kernelbe, és egy cleanup_module() nevű 'end' (cleanup) függvényt, amely közvetlenül az rmmoded előtt kerül meghívásra. Valójában a dolgok megváltoztak a 2.3.13-as kerneltől kezdve. Mostantól tetszőleges nevet használhat egy modul kezdő és záró funkciójához. Valójában az új módszer a preferált módszer. Sokan azonban még mindig az init_module() és cleanup_module() függvényeket használják kezdő és záró függvényeikhez. Ebben a kódban a hello_start()-ot használtuk init függvényként és a hello_end()-et tisztítási függvényként. Egy másik dolog, amit észrevehetett, hogy a printf() függvény helyett printk()-et használtunk. Ennek az az oka, hogy a modul nem nyomtat semmit a konzolra, de naplózza az üzenetet a /var/log/kern.log fájlba. Ezért a kernelmodulok hibakeresésére használják. Ezenkívül a fejlécben nyolc lehetséges naplószintű karakterlánc van megadva, amelyek szükségesek a printk() használatakor. Felsoroltuk őket a súlyosság csökkenésének sorrendjében: - KERN_EMERG: Általában az összeomlást megelőző vészüzenetekhez használják.
- KERN_ALERT: Azonnali cselekvést igénylő helyzet.
- KERN_CRIT: Kritikus állapotok, amelyek gyakran súlyos hardver- vagy szoftverhibákhoz kapcsolódnak.
- KERN_ERR: Hibaállapotok jelentésére szolgál; az eszközillesztők gyakran a KERN_ERR-t használják a hardverproblémák jelentésére.
- KERN_WARNING: Figyelmeztetések olyan problémás helyzetekre, amelyek önmagukban nem okoznak komoly problémákat a rendszerben.
- KERN_NOTICE: Normális, de még mindig figyelmet érdemlő helyzetek. Ezen a szinten számos biztonsági vonatkozású körülmény jelent meg.
- KERN_INFO: Tájékoztató üzenetek. Sok illesztőprogram ezen a szinten nyomtat információkat az indításkor talált hardverről.
- KERN_DEBUG: Az üzenetek hibakeresésére szolgál. A KERN_INFO segítségével nyomtattuk ki az üzenetet. A rendszer felkészítése a kód futtatására: 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 a forráskód összeállításához:
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**Megjegyzés: Ne felejtse el a tabulátorközöket a Makefile-ban A modul összeállítása és betöltése: 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.koA modul tesztelése: 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.