Linux - статьи


"Hello, World" (часть 1): Простейший модуль ядра.


Когда первый пещерный программист высекал свою первую программу для каменного компьютера, это была программа, которая рисовала "Hello, World!" поперек изображения антилопы. Древнеримские учебники по программированию начинались с программы "Salut, Mundi". Я не знаю -- что случается с людьми, которые порывают с этой традицией, но думаю, что лучше этого и не знать. Мы начнем с серии программ "Hello world", на которых разберем различные базовые аспекты создания модулей ядра.

Ниже приводится исходный текст самого простого модуля ядра, какой только возможен. Пока только ознакомьтесь с его содержимым, а компиляцию и запуск модуля мы обсудим в следующем разделе.

Пример 2-1. hello-1.c

/* * hello-1.c - Простейший модуль ядра. */ #include <linux/module.h> /*Необходим для любого модуля ядра */ #include <linux/kernel.h> /*Здесь находится определение KERN_ALERT */

int init_module(void) { printk("<1>Hello world 1.\n");

/* * Если вернуть ненулевое значение, то это * будет воспринято как признак ошибки, * возникшей в процессе работы init_module; * в результате модуль не будет загружен. */ return 0; }

void cleanup_module(void) { printk(KERN_ALERT "Goodbye world 1.\n"); }

Любой модуль ядра должен иметь по меньшей мере хотя бы две функции: функцию инициализации модуля -- init_module(), которую вызывает insmod во время загрузки модуля, и функцию завершения работы модуля -- cleanup_module(), которую вызывает rmmod. Начиная с ядра, версии 2.3.13, требования к именованию начальной и конечной функций были сняты. Теперь вы можете давать им свои имена. Как это сделать будет описано в разделе . Новый метод именования является более предпочтительным, однако многие по-прежнему продолжают использовать имена init_module() и cleanup_module().

Обычно функция init_module()

выполняет регистрацию обработчика какого-либо события или замещает какую-либо функцию в ядре своим кодом (который, как правило, выполнив некие специфические действия, вызывает оригинальную версию функции в ядре). Функция cleanup_module() является полной противоположностью, она производит "откат" изменений, сделаных функцией init_module(), что делает выгрузку модуля безопасной.

И наконец, любой модуль ядра должен подключать заголовочный файл linux/module.h. В нашем примере мы подключали еще один файл -- linux/kernel.h, но лишь для того, чтобы получить доступ к определению KERN_ALERT, которое более подробно будет обсуждаться в



Содержание раздела