Linux-ytimen moduuliohjelmointi: Hello World -ohjelma
Ydinmoduulit ovat koodinpätkiä, jotka voidaan ladata ja purkaa ytimeen pyynnöstä. Ne laajentavat ytimen toimintoja tarvitsematta käynnistää järjestelmää uudelleen. Mukautettuja koodeja voidaan lisätä Linux-ytimiin kahdella tavalla.
- Perustapa on lisätä koodi ytimen lähdepuuhun ja kääntää ydin uudelleen.
- Tehokkaampi tapa tehdä tämä on lisätä koodia ytimeen sen ollessa käynnissä. Tätä prosessia kutsutaan moduulin lataamiseksi, missä moduuli viittaa koodiin, jonka haluamme lisätä ytimeen.
- laiteohjain
- tiedostojärjestelmäohjain ja
- Järjestelmäpuhelut.
/** * @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 );
Selitys yllä olevalle koodille: Ytimen moduuleilla on oltava vähintään kaksi funktiota: "aloitus"-funktio nimeltä init_module(), joka kutsutaan, kun moduuli liitetään ytimeen, ja "end" (puhdistus) -toiminto nimeltä cleanup_module(), joka kutsutaan juuri ennen rmmoded-toimintoa. Itse asiassa asiat ovat muuttuneet ytimen versiosta 2.3.13 alkaen. Voit nyt käyttää mitä tahansa nimeä moduulin aloitus- ja lopetustoiminnoille. Itse asiassa uusi menetelmä on suositeltava menetelmä. Kuitenkin monet ihmiset käyttävät edelleen init_module()- ja cleanup_module():ia aloitus- ja lopetusfunktioihinsa. Tässä koodissa olemme käyttäneet hello_start() init-funktiona ja hello_end() puhdistusfunktiona. Toinen asia, jonka olet ehkä huomannut, on, että printf()-funktion sijasta olemme käyttäneet printk(). Tämä johtuu siitä, että moduuli ei tulosta mitään konsoliin, mutta se kirjaa viestin lokiin /var/log/kern.log. Siksi sitä käytetään ytimen moduulien virheenkorjaukseen. Lisäksi otsikossa on määritelty kahdeksan mahdollista lokitason merkkijonoa, jotka vaaditaan printk(:n) käytössä. Olemme listanneet ne vakavuuden alenevassa järjestyksessä: - KERN_EMERG: Käytetään hätäviesteissä, jotka yleensä edeltävät kaatumista.
- KERN_ALERT: Tilanne, joka vaatii välitöntä toimintaa.
- KERN_CRIT: Kriittiset olosuhteet liittyvät usein vakaviin laitteisto- tai ohjelmistovirheisiin.
- KERN_ERR: Käytetään raportoimaan virhetilanteista; laiteohjaimet käyttävät usein KERN_ERR-koodia laitteisto-ongelmista ilmoittamiseen.
- KERN_WARNING: Varoitukset ongelmatilanteista, jotka eivät sinänsä aiheuta vakavia ongelmia järjestelmässä.
- KERN_NOTICE: Tilanteet, jotka ovat normaaleja, mutta silti huomion arvoisia. Tällä tasolla raportoidaan useita turvallisuuteen liittyviä olosuhteita.
- KERN_INFO: Tiedotusviestit. Monet ohjaimet tulostavat tietoja laitteistosta, jonka he löytävät käynnistyshetkellä tällä tasolla.
- KERN_DEBUG: Käytetään viestien virheenkorjaukseen. Olemme käyttäneet KERN_INFOa viestin tulostamiseen. Järjestelmän valmistelu suorittamaan koodi: 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 lähdekoodin kääntämiseksi:
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**Huomaa: Älä unohda sarkainväliä Makefilessa Moduulin kääntäminen ja lataaminen: 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.koModuulin testaus: 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.