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 - читать книгу онлайн бесплатно, автор Ори Померанц
Тёмная тема

Шрифт:

Сбросить

Интервал:

Закладка:

Сделать

Поскольку никаких наших функций не вызывается когда файл открывается или закрывается, некуда поместить MOD_INC_USE_COUNT и MOD_DEC_USE_COUNT в этом модуле, и если файл открыт и затем модуль удален, не имеется никакого способа избежать проблем. В следующей главе мы рассмотрим более тяжелый в реализации, но более гибкий путь имеющий дело с файлами из /proc, который позволит нам защититься от этой проблемы.

procfs.c

/* procfs.c - create a "file" in /proc

* Copyright (C) 1998-1999 by Ori Pomerantz

*/

/* 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

/* Necessary because we use the proc fs */

#include

/* 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

/* Put data into the proc fs file.

Arguments

=========

1. The buffer where the data is to be inserted, if you decide to use it.

2. A pointer to a pointer to characters. This is useful if you don't want to use the buffer allocated by the kernel.

3. The current position in the file.

4. The size of the buffer in the first argument.

5. Zero (for future use?).

Usage and Return Value

======================

If you use your own buffer, like I do, put its location in the second argument and return the number of bytes used in the buffer.

A return value of zero means you have no further information at this time (end of file). A negative return value is an error condition.

For More Information

====================

The way I discovered what to do with this function wasn't by reading documentation, but by reading the code which used it. I just looked to see what uses the get_info field of proc_dir_entry struct (I used a combination of find and grep, if you're interested), and I saw that it is used in /fs/proc/array.c.

If something is unknown about the kernel, this is usually the way to go. In Linux we have the great advantage of having the kernel source code for free - use it.

*/

int procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int zero) {

int len; /* The number of bytes actually used */

/* This is static so it will still be in memory when we leave this function */

static char my_buffer[80];

static int count = 1;

/* We give all of our information in one go, so if the

* user asks us if we have more information the

* answer should always be no.

*

* This is important because the standard read

* function from the library would continue to issue

* the read system call until the kernel replies

* that it has no more information, or until its * buffer is filled. */

if (offset > 0) return 0;

/* Fill the buffer and get its length */

len = sprintf(my_buffer, "For the %d%s time, go away!\n", count,

(count % 100 > 10 && count % 100 < 14) ? "th" :

(count % 10 == 1) ? "st" : (count % 10 == 2) ? "nd" :

(count % 10 == 3) ? "rd" : "th" );

count++;

/* Tell the function which called us where the buffer is */

*buffer_location = my_buffer;

/* Return the length */

return len;

}

struct proc_dir_entry Our_Proc_File = {

0, /* Inode number - ignore, it will be filled by proc_register[_dynamic] */

4, /* Length of the file name */

"test", /* The file name */

S_IFREG | S_IRUGO, /* File mode - this is a regular file which can be read by its owner, its group, and everybody else */

1, /* Number of links (directories where the file is referenced) */

0, 0, /* The uid and gid for the file - we give it * to root */

80, /* The size of the file reported by ls. */

NULL, /* functions which can be done on the inode (linking, removing, etc.) - we don't support any. */

procfile_read, /* The read function for this file, the function called when somebody tries to read something from it. */

NULL /* We could have here a function to fill the file's inode, to enable us to play with permissions, ownership, etc. */

};

/* Initialize the module - register the proc file */

int init_module() {

/* Success if proc_register[_dynamic] is a success, failure otherwise. */

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

/* In version 2.2, proc_register assign a dynamic

* inode number automatically if it is zero in the

* structure, so there's no more need for

* proc_register_dynamic */

return proc_register(&proc_root, &Our_Proc_File);

#else

return proc_register_dynamic(&proc_root, &Our_Proc_File);

#endif

/* proc_root is the root directory for the proc fs (/proc). This is where we want our file to be located. */

}

/* Cleanup - unregister our file from /proc */

void cleanup_module() {

proc_unregister(&proc_root, Our_Proc_File.low_ino);

}

Использование /proc для ввода

Пока мы имеем два способа генерировать вывод из модулей: мы можем зарегистрировать драйвер устройства и создать mknod файл устройства, или мы можем создать /proc файл. Это позволяет модулю сообщать нам что-нибудь. Единственная проблема в том, что не имеется никакого пути для нас, чтобы возразить. Первый путем, которым мы пошлем ввод модулям, будет запись обратно в файл в системе /proc.

Поскольку файловая система /proc была написана главным образом, чтобы позволить ядру сообщать ситуацию процессам, нет никаких специальных условий для ввода. Структура proc_dir_entry не включает указатель на функцию ввода. Вместо этого, чтобы писать в /proc, мы должны использовать стандартный механизм файловой системы.

В Linux имеется стандартный механизм для регистрации файловой системы. Так как каждая файловая система должна иметь собственные функции, чтобы обработать inode и выполнять файловые операции [3] Различие в том, что операции с файлом имеют дело именно с файлом непосредственно, а inode операции имеют дело с путями ссылки на файл, типа создания связей с ним. , имеется специальная структура, чтобы хранить указатели на все нужные функции, struct inode_operations, который включает указатель на struct file_operations. В /proc всякий раз, когда мы регистрируем новый файл, нам позволяют определить, который struct inode_operations будет использоваться для доступа к этому файлу. Это механизм, который мы используем, struct inode_operations, который включает указатель на struct file_operations, который включает указатели на наши функции module_input и module_output.

Важно обратить внимание что стандартные роли чтения и записи, обращены в ядре. Функции чтения используются для вывода, в то время как функции записи используются для ввода. Причина для этого в том, что чтение и запись относятся к точке зрения пользователя: если процесс читает что-то из ядра, ядро должно вывести это, а если процесс пишет что-то в ядро, оно получает это как ввод.

Другая интересная точка здесь это функция module_permission. Эта функция вызывается всякий раз, когда процесс пробует делать что-либо с файлами системы /proc, и может решить позволить доступ или нет. Сейчас это только основано на операции и uid текущиего пользователя, но в принципе такое разрешение может выдаваться исходя из других параметров, например, что другие процессы делают с тем же самым файлом, времени дня или последнего ввода, который мы получили.

Причина для put_user и get_user в том, что память в Linux (под архитектурой Intel, это может быть различно под некоторыми другими процессорами) сегментирована. Это означает, что указатель, отдельно не ссылается на уникальное место в памяти, а только на место в сегменте памяти, и Вы должны знать, который сегмент памяти нужен. Имеется один сегмент памяти для ядра и по одному на каждый из процессов.

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

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

Шрифт:

Сбросить

Интервал:

Закладка:

Сделать


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

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




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


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


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

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