Програмирање модула Линук кернела: Хелло Ворлд Програм
Модули кернела су делови кода који се могу учитати и учитати у кернел на захтев. Они проширују функционалност кернела без потребе за поновним покретањем система. Прилагођени кодови се могу додати Линук кернелима на два начина.
- Основни начин је додавање кода изворном стаблу кернела и поновно компајлирање кернела.
- Ефикаснији начин је да се то уради додавањем кода у кернел док је покренут. Овај процес се зове учитавање модула где се модул односи на код који желимо да додамо језгру.
- драјвер уређаја
- драјвер система датотека и
- Системски позиви.
/** * @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 );
Објашњење за горњи код: Модули кернела морају имати најмање две функције: функцију 'старт' (иницијализацију) која се зове инит_модуле() која се позива када се модул убаци у језгро и 'енд' (чишћење) функцију која се зове цлеануп_модуле() која се позива непосредно пре него што је рммодед. У ствари, ствари су се промениле почевши од кернела 2.3.13. Сада можете користити било које име за почетну и крајњу функцију модула. У ствари, нова метода је пожељна метода. Међутим, многи људи и даље користе инит_модуле() и цлеануп_модуле() за своје почетне и крајње функције. У овом коду смо користили хелло_старт() као инит функцију и хелло_енд() као функцију чишћења. Још једна ствар коју сте можда приметили је да смо уместо функције принтф() користили принтк(). То је зато што модул неће штампати ништа на конзоли, али ће пријавити поруку у /вар/лог/керн.лог. Због тога се користи за отклањање грешака у модулима кернела. Штавише, постоји осам могућих стрингова на нивоу дневника дефинисаних у заглављу који су потребни док се користи принтк(). Навели смо их по опадајућој озбиљности: - КЕРН_ЕМЕРГ: Користи се за хитне поруке, обично оне које претходе паду.
- КЕРН_АЛЕРТ: Ситуација која захтева хитну акцију.
- КЕРН_ЦРИТ: Критични услови често повезани са озбиљним кваровима хардвера или софтвера.
- КЕРН_ЕРР: Користи се за пријављивање стања грешке; драјвери уређаја често користе КЕРН_ЕРР да пријаве хардверске потешкоће.
- КЕРН_ВАРНИНГ: Упозорења о проблематичним ситуацијама које саме по себи не стварају озбиљне проблеме са системом.
- КЕРН_НОТИЦЕ: Ситуације које су нормалне, али ипак вредне пажње. Бројни безбедносни услови су пријављени на овом нивоу.
- КЕРН_ИНФО: Информативне поруке. Многи управљачки програми штампају информације о хардверу који пронађу у тренутку покретања на овом нивоу.
- КЕРН_ДЕБУГ: Користи се за отклањање грешака у порукама. Користили смо КЕРН_ИНФО за штампање поруке. Припрема система за покретање кода: 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)Макефиле за компајлирање изворног кода:
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**Напомена: Не заборавите размаке на картици у Макефиле-у Састављање и учитавање модула: 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Тестирање модула: 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.