Ori Pomerantz Энциклопедия разработчика модулей ядра Linux Введение Кто должен читать это Замечания о стиле
Изменения
Новое в версии 1.0.1 Новое в версии 1.1.0 Благодарности Благодарности к версии 1.0.1 Благодарности к версии 1.1.0 Hello, world Makefile'ы для модулей ядра Модули ядра из нескольких файлов Файлы символьных устройств Исходники для разных версий ядра Files Файловая система /proc Использование /proc для ввода Работа с файлами устройств (запись и IOCTL) Загрузочные параметры Системные вызовы Отложенные процессы Замена для printk Планирование задач Обработчики прерываний Клавиатура в архитектуре Intel Симметричная многопроцессорность Общие ловушки Различия между версиями 2.0 и 2.2 Что дальше? Goods and Services
Получение книги в бумажном виде Поблагодарите автора Лицензия фонда GNU (The GNU General Public License)
Модули ядра из нескольких файлов Иногда имеет смысл разделить модуль на несколько файлов. В этом случае Вы должны делать следующее:
1. Во всех исходных файлах добавьте строку #define __NO_VERSION__. Это важно, потому что module.h обычно включает определение kernel_version, глобальная переменная версии ядра для которой компилируется модуль. Если Вы нуждаетесь в version.h, Вы должны включить его непосредственно, потому что module.h не будет делать этого после указания __NO_VERSION__.
2. Скомпилируйте все исходные файлы как обычно.
3. Объедините все объектные файлы в один. Под x86 это делается командой:
ld -m elf_i386 -r -o lt;имя_модуляgt;.o lt;1-ый исходный файлgt;.o lt;2-ой исходный файлgt;.o.
Пример такого модуля:
start.c /* start.c
* Copyright (C) 1999 by Ori Pomerantz
*
* "Hello, world" - the kernel module version.
* This file includes just the start routine
*/
/* The necessary header files */
/* Standard in kernel modules */
#include lt;linux/kernel.hgt; /* We're doing kernel work */
#include lt;linux/module.hgt; /* Specifically, a module */
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include lt;linux/modversions.hgt;
#endif
/* Initialize the module */
int init_module() {
printk("Hello, world - this is the kernel speaking\n");
/* If we return a non zero value, it means that
* init_module failed and the kernel module
* can't be loaded */
return 0;
}
stop.c /* stop.c
* Copyright (C) 1999 by Ori Pomerantz
*
* "Hello, world" - the kernel module version. This
* file includes just the stop routine.
*/
/* The necessary header files */
/* Standard in kernel modules */
#include lt;linux/kernel.hgt; /* We're doing kernel work */
#define __NO_VERSION__ /* This isn't "the" file of the kernel module */
#include lt;linux/module.hgt; /* Specifically, a module */
#include lt;linux/version.hgt; /* Not included by module.h because of the __NO_VERSION__ */
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include lt;linux/modversions.hgt;
#endif
/* Cleanup - undid whatever init_module did */
void cleanup_module(){
printk("Short is the life of a kernel module\n");
}
Makefile # Makefile for a multifile kernel module
CC=gcc
MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX
hello.o: start.o stop.o
ld -m elf_i386 -r -o hello.o start.o stop.o
start.o: start.c /usr/include/linux/version.h
$(CC) $(MODCFLAGS) -c start.c
stop.o: stop.c /usr/include/linux/version.h
$(CC) $(MODCFLAGS) -c stop.c