Linux Kernel Module Programmering: Hello World Program
Kjernemoduler er kodebiter som kan lastes og losses i kjernen etter behov. De utvider funksjonaliteten til kjernen uten å måtte starte systemet på nytt. Egendefinerte koder kan legges til Linux-kjerner via to metoder.
- Den grunnleggende måten er å legge til koden i kjernekildetreet og kompilere kjernen på nytt.
- En mer effektiv måte er å gjøre dette ved å legge til kode til kjernen mens den kjører. Denne prosessen kalles å laste modulen der modulen refererer til koden vi ønsker å legge til kjernen.
- enhetsdriver
- filsystemdriver og
- Systemanrop.
/** * @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 );
Forklaring på koden ovenfor: Kjernemoduler må ha minst to funksjoner: en 'start' (initialisering) funksjon kalt init_module() som kalles når modulen er insmoded i kjernen og en 'end' (cleanup) funksjon kalt cleanup_module() som kalles rett før den er rmmoded. Faktisk har ting endret seg fra og med kjernen 2.3.13. Du kan nå bruke hvilket navn du vil for start- og sluttfunksjonene til en modul. Faktisk er den nye metoden den foretrukne metoden. Imidlertid bruker mange fortsatt init_module() og cleanup_module() for start- og sluttfunksjonene. I denne koden har vi brukt hello_start() som init-funksjon og hello_end() som oppryddingsfunksjon. En annen ting du kanskje har lagt merke til er at i stedet for printf()-funksjonen har vi brukt printk(). Dette er fordi modulen ikke vil skrive ut noe på konsollen, men den vil logge meldingen i /var/log/kern.log. Derfor brukes den til å feilsøke kjernemoduler. Dessuten er det åtte mulige loggnivåstrenger definert i overskriften som kreves når du bruker printk(). Vi har listet dem i rekkefølge etter avtagende alvorlighetsgrad: - KERN_EMERG: Brukes for nødmeldinger vanligvis de som går før en krasj.
- KERN_ALERT: En situasjon som krever umiddelbar handling.
- KERN_CRIT: Kritiske forhold ofte relatert til alvorlige maskinvare- eller programvarefeil.
- KERN_ERR: Brukes til å rapportere feiltilstander; enhetsdrivere bruker ofte KERN_ERR for å rapportere maskinvareproblemer.
- KERN_ADVARSEL: Advarsler om problematiske situasjoner som ikke i seg selv skaper alvorlige problemer med systemet.
- KERN_NOTICE: Situasjoner som er normale, men som fortsatt er verdt å merke seg. En rekke sikkerhetsrelaterte forhold rapporteres på dette nivået.
- KERN_INFO: Informasjonsmeldinger. Mange drivere skriver ut informasjon om maskinvaren de finner ved oppstart på dette nivået.
- KERN_DEBUG: Brukes til å feilsøke meldinger. Vi har brukt KERN_INFO for å skrive ut meldingen. Klargjør systemet til å kjøre koden: 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 for å kompilere kildekoden:
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**Merk: Ikke glem tabulatorplassene i Makefile Kompilere og laste inn modulen: 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.koTesting av modulen: 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.