logo

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.
Koska lataamme näitä koodeja ajon aikana eivätkä ne ole osa virallista Linux-ydintä, niitä kutsutaan ladattavaksi kernelmoduuliksi (LKM), joka eroaa perusytimestä. Perusydin sijaitsee /boot-hakemistossa ja ladataan aina, kun käynnistämme koneemme, kun taas LKM:t ladataan sen jälkeen, kun perusydin on jo ladattu. Siitä huolimatta nämä LKM:t ovat suurelta osin osa ydintämme ja ne kommunikoivat perusytimen kanssa toimintojensa suorittamiseksi. LKM:t voivat suorittaa erilaisia ​​tehtäviä, mutta periaatteessa ne kuuluvat kolmeen pääluokkaan
  • laiteohjain
  • tiedostojärjestelmäohjain ja
  • Järjestelmäpuhelut.
Mitä etua LKM:t tarjoavat? Yksi niiden tärkeimmistä eduista on, että meidän ei tarvitse rakentaa ydintä uudelleen aina, kun lisäämme uuden laitteen tai jos päivitämme vanhaa laitetta. Tämä säästää aikaa ja auttaa myös pitämään perusytimen virheettömänä. Hyödyllinen nyrkkisääntö on, että meidän ei pidä vaihtaa perusydintä, kun meillä on toimiva perusydin. Se auttaa myös järjestelmäongelmien diagnosoinnissa. Oletetaan esimerkiksi, että olemme lisänneet moduulin perusytimeen (eli olemme muokanneet perusytimeämme kääntämällä sen uudelleen) ja moduulissa on virhe. Tämä aiheuttaa virheen järjestelmän käynnistyksessä, emmekä koskaan tiedä, mikä ytimen osa aiheuttaa ongelmia. Jos taas lataamme moduulin ajon aikana ja se aiheuttaa ongelmia, tiedämme ongelman välittömästi ja voimme purkaa moduulin, kunnes korjaamme sen. LKM:t ovat erittäin joustavia siinä mielessä, että ne voidaan ladata ja purkaa yhdellä komentorivillä. Tämä auttaa säästämään muistia, koska lataamme LKM: n vain silloin, kun tarvitsemme niitä. Lisäksi ne eivät ole hitaampia kuin perusydin, koska jommankumman kutsuminen on vain koodin lataamista muistin eri osasta. **Varoitus: LKM:t eivät ole käyttäjän avaruusohjelmia. Ne ovat osa ydintä. Heillä on järjestelmän vapaa käyttö, ja ne voivat helposti kaataa sen. 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); 
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.ko 
    Moduulin 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 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.