Předpokládejme, že chceme do linuxového jádra přidat nějaké další funkce.
První nápad, který nás napadne, je vylepšit jádro přidáním dalšího kódu, zkompilováním kódu a uvedením nového jádra nahoru.
Tento proces má ale kromě několika dalších i následující nevýhody:
- Přidaný kód trvale zvětší velikost jádra.
- Celé jádro musí být znovu zkompilováno, aby se změny zkompilovaly.
- To znamená, že aby se změny projevily, musí být počítač restartován.
Řešením výše uvedených problémů je koncept LKM.
LKM je zkratka pro Loadable kernel modules (LKM). Jak název napovídá, LKM jsou moduly, které lze přímo načíst do jádra za běhu.
Zaváděcí modul jádra překonává všechny výše uvedené nedostatky.
- Modul lze zkompilovat samostatně
- Modul lze načíst do jádra za běhu, aniž by bylo nutné restartovat počítač.
- Modul lze kdykoli uvolnit, a proto nemá trvalý vliv na velikost jádra.
Jak vytvořit LKM
Pojďme vytvořit základní načítatelný modul jádra.
#include <linux/module.h> #include <linux/kernel.h> int init_module(void) { printk(KERN_INFO "Welcome.....\n"); return 0; } void cleanup_module(void) { printk(KERN_INFO "Bye....\n"); }
Vidíme tedy, že výše uvedený kód je základní LKM.
- Názvy „init_module“ a „cleanup_module“ jsou standardní názvy pro LKM.
- Pokud se podíváte pozorně, zjistíte, že jsme použili „printk“ místo „printf“. Je to proto, že to není normální programování v C, je to programování na úrovni jádra, které se trochu liší od běžného programování na uživatelské úrovni.
- Aby byl kód zkompilován, musí být zahrnuty hlavičky module.ha kernel.h.
Jak zkompilovat LKM
Ke kompilaci výše uvedeného LKM jsem použil následující Makefile :
obj-m += lkm.o all: sudo make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: sudo make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Upozorňujeme, že příkazy začínající výše uvedeným klíčovým slovem „sudo“ by měly mít jeden tabulátor zleva.
Takže, když je spuštěn výše uvedený příkaz, je pozorován následující výstup:
make: Entering directory `/usr/src/linux-headers-2.6.32-21-generic' CC [M] /home/himanshu/practice/lkm.o Building modules, stage 2. MODPOST 1 modules CC /home/himanshu/practice/lkm.mod.o LD [M] /home/himanshu/practice/lkm.ko make: Leaving directory `/usr/src/linux-headers-2.6.32-21-generic'
Po výše uvedené úspěšné kompilaci najdete soubor .ko ve stejném adresáři, kde proběhla kompilace.
Tento soubor .ko je modul, který se nahraje do jádra. K získání informací o tomto modulu lze použít utilitu modinfo:
$ modinfo lkm.ko filename: lkm.ko srcversion: 19967CB3EAB7B31E643E006 depends: vermagic: 2.6.32.11+drm33.2 SMP mod_unload modversions
Vidíme tedy, že utilita ‚modinfo‘ poskytuje nějaké informace o tomto modulu.
Jak se načítá LKM
Po úspěšné kompilaci a vytvoření modulu je nyní čas jej vložit do jádra, aby se načetl za běhu. Vložení modulu lze provést pomocí následujících dvou utilit:
- modprobe
- insmod
Rozdíl mezi nimi spočívá v tom, že „modprobe“ se stará o to, že pokud je modul závislý na nějakém jiném modulu, pak se nejprve načte tento modul a poté se nahraje hlavní modul. Zatímco nástroj „insmod“ pouze vloží modul (jehož jméno je zadáno) do jádra.
„modprobe“ je tedy lepší nástroj, ale protože náš modul není závislý na žádném jiném modulu, budeme používat pouze „insmod“.
Pro vložení modulu se tedy použije následující příkaz:
$ sudo insmod ./lkm.ko
pokud tento příkaz nehlásí žádnou chybu, znamená to, že LKM je úspěšně načten do jádra.
K uvolnění LKM se používá následující příkaz:
$ sudo rmmod lkm.ko
Opět platí, že pokud tento příkaz nehlásí žádnou chybu, znamená to, že LKM bylo úspěšně staženo z jádra.
Chcete-li zkontrolovat, zda byl modul načten a uvolněn správně, můžeme použít obslužný program dmesg, který poskytuje poslední sadu protokolů tak, jak byly zaznamenány jádrem. Mezi všemi ostatními protokoly uvidíte následující dva řádky:
.... .... [ 4048.333756] Welcome..... [ 4084.205143] Bye....
Pokud se vrátíte ke kódu a uvidíte, uvědomíte si, že se jedná o protokoly ze dvou funkcí v kódu.
Vidíme tedy, že jedna funkce byla volána, když bylo zavoláno „insmod“ a druhá funkce byla volána, když byl zavolán „rmmod“.
Tohle byla jen figurína LKM. Tímto způsobem mnoho fungujících LKM (které provádějí smysluplné úkoly) pracuje uvnitř linuxového jádra.