Эта книга распространяется в надежде на то, что она будет вам полезна, но без каких-либо гарантий, в том числе и без подразумеваемых гарантий высокого спроса или пригодности для специфических целей



страница3/18
Дата21.11.2016
Размер1.25 Mb.
Просмотров4329
Скачиваний0
1   2   3   4   5   6   7   8   9   ...   18

1.2.1. Прежде, чем продолжить


Прежде, чем мы приступим к программированию, необходимо обсудить еще ряд моментов. Любая система имеет свои отличительные черты и каждый из нас имеет разный багаж знаний. Написать, скомпилировать и запустить свою первую программу "Hello World!" для многих может оказаться довольно сложной задачей. Однако, после преодоления этого начального препятствия, работа, как правило, продвигается без особых проблем.

1.2.1.1. Механизм контроля версий


Модули, скомпилированные с одним ядром, могут не загружаться другим ядром, если в ядре включен механизм проверки версий модулей. В большинстве дистрибутивов ядро собирается с такой поддержкой. Мы не собираемся обсуждать проблему контроля версий в этой книге, поэтому нам остается порекомендовать, в случае возникновения проблем, пересобрать ядро без поддержки механизма контроля версий.

1.2.1.2. Работа в XWindow


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

Модули не могут использовать функцию printf() для вывода не экран, но они могут регистрировать сообщения об ошибках, которые в конечном итоге попадают на экран, но только в текстовой консоли. Если же модуль загружается из окна терминала, например xterm, то эти сообщения будут попадать только в системный журнал и не будут выводиться на экран. Чтобы видеть выводимые сообщения на экране, работайте в текстовой консоли (от переводчика: при опробовании примеров из книги мне не удалось вывести ни одного сообщения на экран, так что ищите ваши сообщения в системном журнале, в моем случае это был файл /var/log/kern.log).


1.2.1.3. Проблемы компиляции


Зачастую, дистрибутивостроители распространяют исходные тексты ядра, на которые уже наложены разные нестандартные заплаты. Это может породить определенные проблемы.

Не менее частый случай -- неполный набор заголовочных файлов ядра. Для сборки своих модулей вам потребуются многие заголовочные файлы ядра Linux. А закон Мэрфи гласит: "Отсутствовать будут как раз те файлы, в которых вы больше всего нуждаетесь".

Чтобы избежать этих двух проблем, мы рекомендуем собрать и установить наиболее свежее ядро. Скачать исходные тексты ядра вы сможете на любом из зеркал, распространяющих ядро Linux. За более подробной информацией обращайтесь к "Kernel HOWTO".

Как это ни покажется странным, но проблемы могут крыться и в компиляторе. По-умолчанию gcc может искать заголовочные файлы ядра совсем не там, куда вы их установили (как правило это каталог /usr/src/. Эта проблема легко преодолевается заданием ключа компиляции -I.


Глава 2. Hello World

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


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

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

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

/*


* hello-1.c - Простейший модуль ядра.

*/

#include /* Необходим для любого модуля ядра */



#include /* Здесь находится определение 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, требования к именованию начальной и конечной функций были сняты. Теперь вы можете давать им свои имена. Как это сделать будет описано в разделе Hello World (часть 2). Новый метод именования является более предпочтительным, однако многие по-прежнему продолжают использовать имена init_module() иcleanup_module().

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

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


2.1.1. Знакомство с printk()


Несмотря на столь красноречивое название, функция printk() вовсе не предназначена для вывода информации на экран, даже не смотря на то, что мы использовали ее в своем примере именно для этой цели! Основное назначение этой функции -- дать ядру механизм регистрации событий и предупреждений. Поэтому, каждый вызов printk() сопровождается указанием приоритета, в нашем примере это <1> и KERN_ALERT. Всего в ядре определено 8 различных уровней приоритета для функции printk() и каждый из них имеет свое макроопределение, таким образом нет необходимости писать числа, лишенные смысла (имена уровней приоритета и их числовые значения вы найдете в файле linux/kernel.h). Если уровень приоритета не указывается, то по-умолчанию он принимается равным DEFAULT_MESSAGE_LOGLEVEL.

Найдите время и просмотрите содержимое этого файла. Здесь вы найдете краткое описание значения каждого из уровней. На практике считается дурным тоном указание уровней приоритета числовым значением, например так: <4>. Для этих целей лучше пользоваться именами макроопределений, например: KERN_WARNING.

Если задан уровень ниже, чем int console_loglevel, то сообщение выводится на экран. Если запущены и syslog, и klogd, то сообщение попадет также и в системный журнал /var/log/messages, при этом оно может быть выведено на экран, а может и не выводиться. Мы использовали достаточно высокий уровень приоритета KERN_ALERT для того, чтобы гарантировать вывод сообщения на экран функцией printk(). Когда вы вплотную займетесь созданием модулей ядра, вы будете использовать уровни приоритета наиболее подходящие под конкретную ситуацию.


Каталог: files
files -> Основная часть 1 История создания школы
files -> Методические рекомендации по проведению Дня Знаний, посвященного Году кино в РФ
files -> Подросток и компьютерные игры
files -> Программа духовно-нравственного развития и воспитания обучающихся на уровне среднего общего образования
files -> Правила закаливания… Выпуск №1. Чтоб улыбка сияла. Мама первый стоматолог
files -> О существовании значения игры преследования
files -> Учебное пособие по нейрохирургии. Часть I. Краткая история нейрохирургии. Черепно-мозговая травма санкт-Петербург 2015


Поделитесь с Вашими друзьями:
1   2   3   4   5   6   7   8   9   ...   18


База данных защищена авторским правом ©nethash.ru 2019
обратиться к администрации

войти | регистрация
    Главная страница


загрузить материал