Linux Kernel Module Programmering: Hello World Program
Kärnmoduler är kodbitar som kan laddas och laddas ur i kärnan på begäran. De utökar kärnans funktionalitet utan att behöva starta om systemet. Anpassade koder kan läggas till Linux-kärnor via två metoder.
- Det grundläggande sättet är att lägga till koden i kärnans källträd och kompilera om kärnan.
- Ett mer effektivt sätt är att göra detta genom att lägga till kod till kärnan medan den körs. Denna process kallas att ladda modulen där modulen refererar till koden som vi vill lägga till i kärnan.
- enhetsdrivrutin
- filsystemdrivrutin och
- Systemsamtal.
/** * @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 );
Förklaring till ovanstående kod: Kärnmoduler måste ha minst två funktioner: en 'start' (initiering) funktion som heter init_module() som anropas när modulen är inbyggd i kärnan och en 'end' (cleanup) funktion som heter cleanup_module() som anropas precis innan den är rmmoded. Saker och ting har faktiskt förändrats från och med kärnan 2.3.13. Du kan nu använda vilket namn du vill för start- och slutfunktionerna för en modul. I själva verket är den nya metoden den föredragna metoden. Men många använder fortfarande init_module() och cleanup_module() för sina start- och slutfunktioner. I den här koden har vi använt hello_start() som init-funktion och hello_end() som rensningsfunktion. En annan sak som du kanske har lagt märke till är att istället för printf()-funktionen har vi använt printk(). Detta beror på att modulen inte kommer att skriva ut något på konsolen men den kommer att logga meddelandet i /var/log/kern.log. Därför används den för att felsöka kärnmoduler. Dessutom finns det åtta möjliga loggnivåsträngar definierade i rubriken som krävs när du använder printk(). Vi har listat dem i ordning efter minskande svårighetsgrad: - KERN_EMERG: Används för nödmeddelanden vanligtvis de som föregår en krasch.
- KERN_ALERT: En situation som kräver omedelbar åtgärd.
- KERN_CRIT: Kritiska tillstånd ofta relaterade till allvarliga hårdvaru- eller mjukvarufel.
- KERN_ERR: Används för att rapportera feltillstånd; enhetsdrivrutiner använder ofta KERN_ERR för att rapportera hårdvaruproblem.
- KERN_VARNING: Varningar om problematiska situationer som inte i sig skapar allvarliga problem med systemet.
- KERN_NOTICE: Situationer som är normala men ändå värda att notera. Ett antal säkerhetsrelaterade tillstånd rapporteras på denna nivå.
- KERN_INFO: Informationsmeddelanden. Många drivrutiner skriver ut information om hårdvaran de hittar vid uppstart på denna nivå.
- KERN_DEBUG: Används för att felsöka meddelanden. Vi har använt KERN_INFO för att skriva ut meddelandet. Förbereder systemet för att köra 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 för att kompilera källkoden:
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**Obs: Glöm inte tabbutrymmena i Makefile Kompilera och ladda 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.koTesta 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.