Linux-Kernel-Modulprogrammierung: Hello World-Programm
Kernelmodule sind Codeteile, die bei Bedarf in den Kernel geladen und entladen werden können. Sie erweitern die Funktionalität des Kernels, ohne dass ein Neustart des Systems erforderlich ist. Benutzerdefinierte Codes können auf zwei Arten zu Linux-Kerneln hinzugefügt werden.
- Der grundlegende Weg besteht darin, den Code zum Kernel-Quellbaum hinzuzufügen und den Kernel neu zu kompilieren.
- Eine effizientere Möglichkeit besteht darin, Code zum Kernel hinzuzufügen, während dieser ausgeführt wird. Dieser Vorgang wird als Laden des Moduls bezeichnet, wobei sich Modul auf den Code bezieht, den wir dem Kernel hinzufügen möchten.
- Gerätetreiber
- Dateisystemtreiber und
- Systemaufrufe.
/** * @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 );
Erklärung zum obigen Code: Kernel-Module müssen mindestens zwei Funktionen haben: eine „Start“-Funktion (Initialisierung) namens „init_module()“, die aufgerufen wird, wenn das Modul in den Kernel eingefügt wird, und eine „End“-Funktion (Bereinigung) namens „cleanup_module()“, die unmittelbar vor dem RM-Modem aufgerufen wird. Tatsächlich haben sich die Dinge ab Kernel 2.3.13 geändert. Sie können nun für die Start- und Endfunktionen eines Moduls einen beliebigen Namen verwenden. Tatsächlich ist die neue Methode die bevorzugte Methode. Allerdings verwenden viele Leute immer noch init_module() und cleanup_module() für ihre Start- und Endfunktionen. In diesem Code haben wir hello_start() als Init-Funktion und hello_end() als Bereinigungsfunktion verwendet. Eine weitere Sache, die Ihnen vielleicht aufgefallen ist, ist, dass wir anstelle der printf()-Funktion printk() verwendet haben. Dies liegt daran, dass das Modul nichts auf der Konsole ausgibt, die Meldung jedoch in /var/log/kern.log protokolliert. Daher wird es zum Debuggen von Kernelmodulen verwendet. Darüber hinaus sind im Header acht mögliche Loglevel-Strings definiert, die bei der Verwendung von printk() erforderlich sind. Wir haben sie in der Reihenfolge abnehmender Schwere aufgelistet: - KERN_EMERG: Wird für Notfallmeldungen verwendet, normalerweise solche, die einem Absturz vorausgehen.
- KERN_ALERT: Eine Situation, die sofortiges Handeln erfordert.
- KERN_CRIT: Kritische Zustände, die häufig mit schwerwiegenden Hardware- oder Softwarefehlern zusammenhängen.
- KERN_ERR: Wird zum Melden von Fehlerbedingungen verwendet. Gerätetreiber verwenden häufig KERN_ERR, um Hardwareprobleme zu melden.
- KERN_WARNING: Warnungen vor problematischen Situationen, die an sich keine ernsthaften Probleme mit dem System verursachen.
- KERN_NOTICE: Situationen, die normal sind, aber dennoch bemerkenswert sind. Auf dieser Ebene werden eine Reihe sicherheitsrelevanter Bedingungen gemeldet.
- KERN_INFO: Informationsnachrichten. Viele Treiber geben auf dieser Ebene Informationen über die Hardware aus, die sie beim Start finden.
- KERN_DEBUG: Wird zum Debuggen von Nachrichten verwendet. Wir haben KERN_INFO verwendet, um die Nachricht auszudrucken. Vorbereiten des Systems für die Ausführung des Codes: 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 zum Kompilieren des Quellcodes:
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**Hinweis: Vergessen Sie nicht die Tabulator-Leerzeichen in Makefile Kompilieren und Laden des Moduls: 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.koTesten des Moduls: 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.