Kodola moduļi ir koda daļas, kuras pēc pieprasījuma var ielādēt un izlādēt kodolā. Tie paplašina kodola funkcionalitāti bez nepieciešamības pārstartēt sistēmu. Pielāgotus kodus var pievienot Linux kodoliem, izmantojot divas metodes. - Galvenais veids ir pievienot kodu kodola avota kokam un pārkompilēt kodolu.
- Efektīvāks veids ir to izdarīt, pievienojot kodu kodolam, kamēr tas darbojas. Šo procesu sauc par moduļa ielādi, kur modulis attiecas uz kodu, kuru vēlamies pievienot kodolam.
Tā kā mēs ielādējam šos kodus izpildlaikā un tie nav daļa no oficiālā Linux kodola, tos sauc par ielādējamu kodola moduli (LKM), kas atšķiras no bāzes kodola. Bāzes kodols atrodas /boot direktorijā un vienmēr tiek ielādēts, kad mēs sāknējam mūsu mašīnu, turpretim LKM tiek ielādēti pēc tam, kad pamata kodols jau ir ielādēts. Tomēr šie LKM ir ļoti liela daļa no mūsu kodola, un tie sazinās ar pamata kodolu, lai pabeigtu savas funkcijas. LKM var veikt dažādus uzdevumus, bet būtībā tie ietilpst trīs galvenajās kategorijās - ierīces draiveris
- failu sistēmas draiveri un
- Sistēmas zvani.
Tātad, kādas priekšrocības piedāvā LKM? Viena no galvenajām to priekšrocībām ir tā, ka mums nav jāpārveido kodols katru reizi, kad pievienojam jaunu ierīci vai jauninām veco ierīci. Tas ietaupa laiku un palīdz arī uzturēt mūsu bāzes kodola kļūdas. Noderīgs īkšķis ir tāds, ka mums nevajadzētu mainīt savu bāzes kodolu, kad mums ir funkcionējošs bāzes kodols. Tas arī palīdz diagnosticēt sistēmas problēmas. Piemēram, pieņemsim, ka esam pievienojuši moduli bāzes kodolam (t.i., esam modificējuši savu bāzes kodolu, to pārkompilējot), un modulī ir kļūda. Tas radīs kļūdu sistēmas sāknēšanas laikā, un mēs nekad neuzzināsim, kura kodola daļa rada problēmas. Savukārt, ja mēs ielādējam moduli izpildlaikā un tas rada problēmas, mēs nekavējoties uzzināsim problēmu un varēsim izlādēt moduli, līdz to izlabosim. LKM ir ļoti elastīgi tādā ziņā, ka tos var ielādēt un izkraut ar vienu komandrindu. Tas palīdz ietaupīt atmiņu, jo mēs ielādējam LKM tikai tad, kad mums tie ir nepieciešami. Turklāt tie nav lēnāki par bāzes kodolu, jo, izsaucot kādu no tiem, vienkārši tiek ielādēts kods no citas atmiņas daļas. **Brīdinājums: LKM nav lietotāja kosmosa programmas. Tie ir daļa no kodola. Viņiem ir brīva sistēmas darbība, un tie var viegli to avarēt. So now that we have established the use loadable kernel modules we are going to write a hello world kernel module. That will print a message when we load the module and an exit message when we unload the module. Code: CPP /** * @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 worldn'); return 0; } static void __exit hello_end(void) { printk(KERN_INFO 'Goodbye Mr.n'); } module_init(hello_start); module_exit(hello_end);
Iepriekš minētā koda skaidrojums: Kodola moduļiem ir jābūt vismaz divām funkcijām: funkcijai "sākt" (inicializācija) ar nosaukumu init_module(), kas tiek izsaukta, kad modulis tiek ievietots kodolā, un funkcijai "beigt" (tīrīšana) ar nosaukumu cleanup_module(), kas tiek izsaukta tieši pirms rmmoded. Faktiski lietas ir mainījušās, sākot ar kodolu 2.3.13. Tagad moduļa sākuma un beigu funkcijām varat izmantot jebkuru nosaukumu. Faktiski jaunā metode ir vēlamā metode. Tomēr daudzi cilvēki joprojām izmanto init_module() un cleanup_module() sākuma un beigu funkcijām. Šajā kodā mēs esam izmantojuši hello_start () kā init funkciju un hello_end () kā tīrīšanas funkciju. Vēl viena lieta, ko jūs, iespējams, pamanījāt, ir tā, ka funkcijas printf () vietā esam izmantojuši printk (). Tas ir tāpēc, ka modulis neko nedrukās konsolē, bet reģistrēs ziņojumu mapē /var/log/kern.log. Tāpēc to izmanto kodola moduļu atkļūdošanai. Turklāt galvenē ir definētas astoņas iespējamās loglevel virknes, kas ir nepieciešamas, izmantojot printk (). Mēs esam tos uzskaitījuši smaguma samazināšanas secībā: - KERN_EMERG: izmanto ārkārtas ziņojumiem, parasti tiem, kas ir pirms avārijas.
- KERN_ALERT: situācija, kurā nepieciešama tūlītēja rīcība.
- KERN_CRIT: kritiski apstākļi, kas bieži saistīti ar nopietnām aparatūras vai programmatūras kļūmēm.
- KERN_ERR: izmanto, lai ziņotu par kļūdu apstākļiem; ierīču draiveri bieži izmanto KERN_ERR, lai ziņotu par aparatūras problēmām.
- KERN_WARNING: Brīdinājumi par problemātiskām situācijām, kas pašas par sevi nerada nopietnas problēmas sistēmā.
- KERN_NOTICE: situācijas, kas ir normālas, bet tomēr ir jāņem vērā. Šajā līmenī tiek ziņots par vairākiem ar drošību saistītiem apstākļiem.
- KERN_INFO: informatīvie ziņojumi. Daudzi draiveri šajā līmenī izdrukā informāciju par aparatūru, ko viņi atrod startēšanas laikā.
- KERN_DEBUG: izmanto ziņojumu atkļūdošanai.
Mēs esam izmantojuši KERN_INFO, lai izdrukātu ziņojumu. Sistēmas sagatavošana koda palaišanai: 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 avota koda apkopošanai: 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
**Piezīme: neaizmirstiet lietotnē Makefile izmantot tabulēšanas atstarpes Moduļa kompilēšana un ielāde: 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.ko
Moduļa pārbaude: 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 modversions
To 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.