MODULE_AUTHOR('Denis Kolisnichenko [email protected]');

MODULE_DESCRIPTION('Linux kernel module');

int init_module() {

 return 0;

}

void cleanup_module() {

 return 0;

}

Макросы MODULE_AUTHOR и MODULE_DESCRIPTION определены в заголовочном файле module.h, поэтому никаких дополнительных заголовочных файлов подключать не нужно.

При необходимости модуль может выводить на консоль сообщения, например, о невозможности инициализации устройства. Выводимые модулем сообщения будут запротоколированы службой протоколирования ядра — демоном klogd. Выводить сообщения нужно не с помощью функции printf(), а функцией printk(). В этом случае сообщения не только окажутся на системной консоли, но и будут запротоколированы в файле /var/log/messages.

Сейчас мы напишем модуль, который будет выводить сообщения при загрузке и при удалении.

Листинг 28.4. Использование функции printk() (module.с)

#define MODULE

#define __KERNEL__

#include <linux/module.h>

#include <linux/kernel.h> // printk

MODULE_AUTHOR{'Denis Kolisnichenko [email protected]');

MODULE_DESCRIPTION('Linux kernel module');

int init_module() {

 printk('My module: Starting... ');

 return 0;

}

void cleanup_module() {

 printk('My module: Stopping... ');

 return 0;

}

28.2. Компиляция модуля

Компилировать мы будем файл module.c. Для этого понадобится установленный компилятор gcc, заголовочные файлы и исходные тексты ядра. Если вы дочитали книгу до этой главы, то у вас уже должны быть установлены пакеты:

1. cpp — препроцессор cpp;

2. binutils — набор различных утилит (as, gprof, ld);

3. glibc-kerheaders — заголовочные файлы ядра;

4. glibc-devel — вспомогательные файлы для разработки приложений с использованием стандартной библиотеки С;

5. gcc — компилятор gcc.

Осталось установить пакет kernel-source — исходные тексты ядра Linux. Кроме того, нужно убедиться, что ваше ядро поддерживает динамически загружаемые модули (п. 20.3.2.3). Если опция Enable loadable module support выключена, ее нужно включить, сохранить файл конфигурации ядра и перекомпилировать ядро.

Компилятор gcc нужно вызвать со множеством опций, поэтому для облегчения себе работы мы напишем make-файл (п. 21.2):

Листинг 28.5. Makefile для сборки модуля

CC=gcc

PATH=/usr/include /usr/src/linux-2.4/include

MODFLAGS:= -O3 -Wall -DLINUX -D__KERNEL__ -I$(PATH)

module.o: module.с

$(CC) $(MODFLAGS) -c module.с

Опции компилятора означают следующее:

♦ O3: будет использован третий уровень оптимизации (что это такое, вы узнаете в справочной системе gcc: man gcc);

♦ Wall: включаем все предупреждения;

♦ DLINUX: генерируем код для Linux;

♦ I$(РАТН): определяем путь поиска заголовочных файлов. По умолчанию компилятор ищет файлы заголовков в каталоге /usr/include, но там может и не быть нужных файлов. Например, для дистрибутива ALT Linux (ядро 2.4.21) файлы заголовков находятся в каталоге /usr/include/linux-2.4.21rel-std- up.

Поместите make-файл в тот же каталог, где находится module.c, и выполните команду make. После ее выполнения вы получите файл module.o, который будет находиться в том же каталоге.

# insmod module.o

Вы увидите сообщение My module: Starting... Это же сообщение будет записано в файл протокола /var/log/messages.

28.3. Работа с устройствами

Мы только что написали модуль ядра, который можно установить, удалить, который выводит сообщения, но ничего полезного он не делает. Усложним нашу задачу: напишем модуль, управляющий некоторым устройством /dev/device. Данного устройства в нашей системе нет, поэтому нам его нужно создать, но этим мы займемся чуть позже.

Перед тем, как приступить к написанию драйвера устройства, нужно поговорить о самих устройствах. Устройства бывают трех типов:

♦ Символьные: чтение и запись устройства выполняются посимвольно. Примером такого устройства может послужить последовательный порт.

♦ Блочные: чтение и запись устройства выполняются блоками, как правило, по 512 или 1024 байта. Самый яркий пример блочного устройства — жесткий диск.

♦ Сетевые: файлов этих устройств вы не найдете в каталоге /dev, поскольку использование файловой системы, то есть работа с этими устройствами как с файлами, неэффективно. Пример — сетевая карта (ethX).

Существуют устройства, которые нельзя отнести ни к одному типу, поскольку они не принимают и не передают данные. Пример: RTC (Real Time Clock).

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату