В этой статье речь пойдет о том, как создать модулья ядра Linux.
Так уже задуман Linux, что в нем есть пространство ядра (kernel-space) и пользователя (user-space). В пространстве пользователя выполняются все самые обычные программы, а вот взаимодействие с устройствами происходит при помощи кода, который выполняется из пространства ядра. Там же (в пространсве ядра) выполняется планировщик операционной системы и все служебные функции. Взаимодествие же программ из пространства пользователя с ядром происходит при помощи системных вызовов (system calls), но сейчас не о них, а о том, как создать простой модуль ядра.
Задачей данного модуля будет вывод строки hello world.
Ядро не может вывести строку нам в терминал. Зато оно может вывести её в лог (это делает функция printk). А мы позже его просмотрим при помощи утилиты dmesg.
Приступим.
Для того, чтобы собрать модуль нам понадобятся заголовки ядра. Установите пакет linux-headers / kernel-devel в зависимости от вашего дистрибутива. Это хорошо гуглится, поэтому не будем заострять внимание.
В любом модуле ядра Linux должно быть хотябы 2 функции. Точка входа й выхода.
Функция входа должна возвращать 0 в случа нормальной загрузки. После определения функций их нужно зарегистрировать.
Создайте файл blablamod.c:
#include <inux/init.h>
#include <linux/module.h>
#include "blablamod.h"
static int __init blablamod_init( void ) {
printk(KERN_NOTICE "BlablaModule loaded!\n" );
return 0;
}
static void __exit blablamod_exit( void ) {
printk(KERN_NOTICE "BlablaModule unloaded!\n" );
}
module_init( blablamod_init );
module_exit( blablamod_exit );
Файл blablamod.h:
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dmitrey Salnikov <mr.dimas@meta.ua>");
На этом программирование модуля заканчивается. Нам нужно его собрать. Для этого нужно создать Makefile.
KDIR = /lib/modules/$(shell uname -r)/build
PWD = $(shell pwd)
TARGET = blablamod
obj-m := $(TARGET).o
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
@rm -f *.o .*.cmd .*.flags *.mod.c *.order
@rm -f .*.*.cmd *~ *.*~ TODO.*
@rm -fR .tmp*
@rm -rf .tmp_versions
disclean: clean
@rm *.ko *.symvers
Он в принципе не особо меняется. Шаблонный такой.
Можно собирать.
$ make make -C /lib/modules/3.19.0-rc2+/build M=/home/lamazavr/kernel_module/blablamod_01 modules make[1]: вход в каталог «/home/lamazavr/src/kernel/linux» CC [M] /home/lamazavr/kernel_module/blablamod_01/blablamod.o Building modules, stage 2. MODPOST 1 modules CC /home/lamazavr/kernel_module/blablamod_01/blablamod.mod.o LD [M] /home/lamazavr/kernel_module/blablamod_01/blablamod.ko make[1]: выход из каталога «/home/lamazavr/src/kernel/linux»
Теперь можно загружать модуль.
sudo insmod blablamod.ko
Можно проверять лог.
dmesg
В конце должно быть что-то вроде этого:
[ 544.652030] BlablaModule loaded!
Теперь выгружаем.
sudo rmmod blablamod
Опять проверяем лог. Видим там такое:
[ 640.847625] BlablaModule unloaded!
Ну и ради интереса проверим информацию о модуле.
modinfo blablamod.ko filename: /home/lamazavr/kernel_module/blablamod_01/blablamod.ko author: Dmitrey Salnikov <mr.dimas@meta.ua> license: GPL depends: vermagic: 3.19.0-rc2+ SMP mod_unload
Вот и все.
Весь код на github.




