LibKing » Книги » comp-programming » Ори Померанц - Энциклопедия разработчика модулей ядра Linux

Ори Померанц - Энциклопедия разработчика модулей ядра Linux

Тут можно читать онлайн Ори Померанц - Энциклопедия разработчика модулей ядра Linux - бесплатно полную версию книги (целиком). Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте LibKing.Ru (ЛибКинг) или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
libking
  • Название:
    Энциклопедия разработчика модулей ядра Linux
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    4/5. Голосов: 101
  • Избранное:
    Добавить в избранное
  • Ваша оценка:

Ори Померанц - Энциклопедия разработчика модулей ядра Linux краткое содержание

Энциклопедия разработчика модулей ядра Linux - описание и краткое содержание, автор Ори Померанц, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Linux Kernel Module Programming Guide свободная книга; Вы можете воспроизводить и/или изменять ее в соответствии с версией 2 (или, в вашем случае, любой более поздней версией) GNU General Public License, опубликованной Free Software Foundation. Версия 2 поставляется с этим документом в Приложении E.

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

Автор поощряет широкое распространение этой книги для персонального или коммерческого использования, если вышеупомянутое примечание относительно авторского права остается неповрежденным, и распространитель твердо придерживается условий GNU General Public License (см. Приложение E). Вы можете копировать и распространять эту книгу бесплатно или для получения прибыли. Никакое явное разрешение не требуется от автора для воспроизводства этой книги в любой среде, физической или электронной.

Обратите внимание, производные работы и переводы этого документа должны быть помещены согласно GNU General Public License, и первоначальное примечание относительно авторского права должно остаться неповрежденным. Если Вы пожертвовали новый материал этой книге, Вы должны сделать исходный текст доступным для ваших изменений. Пожалуйста делайте изменения и модификации, доступные непосредственно поддерживающему данный проект Ori Pomerantz. Он объединит модификации и обеспечит непротиворечивость изменений для всего Linux сообщества.

Если Вы планируете издавать и распространять эту книгу коммерчески, пожертвования, лицензионные платежи, и/или напечатанные копии будут высоко оценены автором и Linux Documentation Project (LDP). Содействие таким образом показывает вашу поддержку свободного программного обеспечения и Linux Documentation Project. Если Вы имеете вопросы или комментарии, пожалуйста войдите в контакт с автором по адресу, приведенному выше.

Энциклопедия разработчика модулей ядра Linux - читать онлайн бесплатно полную версию (весь текст целиком)

Энциклопедия разработчика модулей ядра Linux - читать книгу онлайн бесплатно, автор Ори Померанц
Тёмная тема

Шрифт:

Сбросить

Интервал:

Закладка:

Сделать

Когда система была установлена, все файлы устройств были созданы командой mknod. Не имеется никакой технической причины, по которой они должны быть в каталоге /dev, это только полезное соглашение. При создании файла устройства для целей тестирования, как с упражнением здесь, вероятно имело бы смысл поместить его в каталог, где Вы компилируете модуль.

Устройства разделены на два типа: символьные и блочные. Различие в том, что блочные имеют буфер для запросов, так что они могут выбирать в каком порядке им отвечать. Это важно в случае устройств памяти, где скорее понадобится читать или писать сектора, которые ближе друг к другу, чем те, которые находятся далеко. Другое различие: блочные устройства могут принимать ввод и возвращать вывод только в блоках (чей размер может измениться согласно устройству), в то время как символьные устройства могут использовать столько байтов, сколько нужно. Большинство устройств в мире символьно, потому что они не нуждаются в этом типе буферизации и не работают с фиксированным размером блока. Вы можете узнать, является ли устройство блочным или символьным, рассматривая первый символ в выводе ls -l. Если это "b", значит устройство блочное, а если "c", то символьное.

Этот модуль разделен на две отдельных части: часть модуля, которая регистрирует устройство и часть драйвера устройства. init_module вызывает module_register_chrdev, чтобы добавить драйвер устройства к символьной таблице драйверов устройств ядра. Этот вызов также возвращает главный номер, который нужно использовать для драйвера. Функция cleanup_module вычеркивает из списка устройство.

Это (регистрация и отмена регистрации) основные функциональные возможности этих двух функций. Действия в ядре не выполняются по собственной инициативе, подобно процессам, а вызываются процессами через системные вызовы или аппаратными устройствами через прерывания или другими частями ядра (просто вызывая специфические функции). В результате, когда Вы добавляете код к ядру, вы регистрируете его как драйвер для некоторого типа события, и когда Вы удаляете его, вы отменяете регистрацию.

Драйвер устройства выполняет четыре действия (функции), которые вызываются, когда кто-то пробует делать что-либо с файлом устройства, который имеет наш главный номер. Ядро знает, что вызвать их надо через структуру file_operations, Fops, который был дан, когда устройство было зарегистрировано, включает указатели на те четыре функции, которые данное устройство выполняет.

Еще мы должны помнить, что мы не можем позволять модулю выгружаться командой rmmod всякий раз, когда root захочет его выгрузить. Причина в том что, если файл устройства открыт процессом, и мы удаляем модуль, то использование файла вызвало бы обращение к точке памяти где располагалась соответствующая функция. Если мы удачливы, никакой другой код не был загружен туда, и мы получим уродливое сообщение об ошибках. Если мы неудачливы (обычно так и бывает), другой модуль был загружен в то же самое место, что означает переход в середину другой функции внутри ядра. Результаты этого невозможно предсказывать, но они не могут быть положительны.

Обычно, когда Вы не хотите выполнять что-либо, Вы возвращаете код ошибки (отрицательное число) из функции, которая делает данное действие. С cleanup_module такой фокус не пройдет: если cleanup_module вызван, модуль завершился. Однако, имеется счетчик использований, который считает, сколько других модулей используют этот модуль, названный номером ссылки (последний номер строки в /proc/modules). Если это число не нулевое, rmmod будет терпеть неудачу. Счетчик модульных ссылок доступен в переменной mod_use_count_. Так как имеются макрокоманды, определенные для обработки этой переменной (MOD_INC_USE_COUNT и MOD_DEC_USE_COUNT), мы предпочитаем использовать их, а не mod_use_count_ непосредственно, так что мы будем в безопасности, если реализация изменится в будущем.

chardev.c

/* chardev.c

* Copyright (C) 1998-1999 by Ori Pomerantz

*

* Create a character device (read only)

*/

/* The necessary header files */

/* Standard in kernel modules */

#include /* We're doing kernel work */

#include /* Specifically, a module */

/* Deal with CONFIG_MODVERSIONS */

#if CONFIG_MODVERSIONS==1

#define MODVERSIONS

#include

#endif

/* For character devices */

#include /* The character device definitions are here */

#include /* A wrapper which does next to nothing at present, but may help for compatibility with future versions of Linux */

/* In 2.2.3 /usr/include/linux/version.h includes a macro for this, but 2.0.35 doesn't - so I add it here if necessary. */

#ifndef KERNEL_VERSION

#define KERNEL_VERSION(a,b,c)

((a)*65536+(b)*256+(c))

#endif

/* Conditional compilation. LINUX_VERSION_CODE is the code (as per KERNEL_VERSION) of this version. */

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)

#include /* for put_user */

#endif

#define SUCCESS 0

/* Device Declarations **************************** */

/* The name for our device, as it will appear in /proc/devices */

#define DEVICE_NAME "char_dev"

/* The maximum length of the message from the device */

#define BUF_LEN 80

/* Is the device open right now? Used to prevent concurent access into the same device */

static int Device_Open = 0;

/* The message the device will give when asked */

static char Message[BUF_LEN];

/* How far did the process reading the message get? Useful if the message is larger than the size of the buffer we get to fill in device_read. */

static char *Message_Ptr;

/* This function is called whenever a process attempts to open the device file */

static int device_open(struct inode *inode, struct file *file) {

static int counter = 0;

#ifdef DEBUG

printk("device_open(%p,%p)\n", inode, file);

#endif

/* This is how you get the minor device number in case you have more than one physical device using the driver. */

printk("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF);

/* We don't want to talk to two processes at the same time */

if (Device_Open) return -EBUSY;

/* If this was a process, we would have had to be

* more careful here.

*

* In the case of processes, the danger would be

* that one process might have check Device_Open

* and then be replaced by the schedualer by another

* process which runs this function. Then, when the

* first process was back on the CPU, it would assume

* the device is still not open.

*

* However, Linux guarantees that a process won't be

* replaced while it is running in kernel context.

*

* In the case of SMP, one CPU might increment

* Device_Open while another CPU is here, right after

* the check. However, in version 2.0 of the

* kernel this is not a problem because there's a lock

* to guarantee only one CPU will be kernel module at

* the same time. This is bad in terms of

* performance, so version 2.2 changed it.

* Unfortunately, I don't have access to an SMP box

* to check how it works with SMP. */

Device_Open++;

/* Initialize the message. */

sprintf(Message, "If I told you once, I told you %d times - %s", counter++, "Hello, world\n");

/* The only reason we're allowed to do this sprintf

* is because the maximum length of the message

* (assuming 32 bit integers - up to 10 digits

* with the minus sign) is less than BUF_LEN, which

* is 80. BE CAREFUL NOT TO OVERFLOW BUFFERS,

* ESPECIALLY IN THE KERNEL!!! */

Message_Ptr = Message;

/* Make sure that the module isn't removed while

* the file is open by incrementing the usage count

Читать дальше
Тёмная тема

Шрифт:

Сбросить

Интервал:

Закладка:

Сделать


Ори Померанц читать все книги автора по порядку

Ори Померанц - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Энциклопедия разработчика модулей ядра Linux отзывы


Отзывы читателей о книге Энциклопедия разработчика модулей ядра Linux, автор: Ори Померанц. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
Большинство книг на сайте опубликовано легально на правах партнёрской программы ЛитРес. Если Ваша книга была опубликована с нарушениями авторских прав, пожалуйста, направьте Вашу жалобу на PGEgaHJlZj0ibWFpbHRvOmFidXNlQGxpYmtpbmcucnUiIHJlbD0ibm9mb2xsb3ciPmFidXNlQGxpYmtpbmcucnU8L2E+ или заполните форму обратной связи.
img img img img img