проект книги: "Модули ядра Linux"

Здесь будут размещаться ссылки и отзывы на интересные публикации по Linux

Модераторы: Olej, vikos

Правила форума
Запрещается помещать сообщения, не имеющие отношения к обсуждаемой статье. Все такие сообщения будут удаляться непосредствено после обнаружения.
bose
Писатель
Сообщения: 107
Зарегистрирован: 23 фев 2012, 14:41
Откуда: Киев
Контактная информация:

Re: проект книги: "Модули ядра Linux"

Непрочитанное сообщение bose » 02 мар 2012, 14:00

Olej писал(а): Именно из-за того, о чём я написал, я считаю эту книгу очень неудачной, из-за того, что их примеры - бесполезны, а без примеров кода всё изложение становится голословным. Их изложение меня просто доводит до бешенства!
+100 :-) Есть такая болячка у большинства авторов. Когда читателю мало того что нужно приложить усилия чтобы освоить новый материал, нужно ещё вникнуть в виртаульную проблему придуманную автором для разъяснения материала. В университете преподаватель по ООП рекомендовал прочитать Гради Буча "Объектно-ориентированный анализ и проектирование с примерами приложений на С++" и в качестве лаб работы разобрать и реализовать его пример "метеорологическая станция" (ну и у него вся книга вокруг примера теплицы для овощей). Как я тогда не взлюбил ООП :-D . Для меня эта тема была так не интересна, скучна и уныла, что автоматически это перенеслось на ООП. Другой пример Дон Кнут и его "Искусство программирования" - всё классно, но алгоритмы на ассемблере для виртуального (M)MIX, как для меня, выглядят не "сочно", и тяжело читаемы. Сам язык можно б было запомнить, но в реальности он нигде не используется и по-этому быстро забывается. В итоге что бы через год-два открыть том что б подсмотреть идею какого-нибудь алгоритма, нужно снова потратить время для повторения архитектуры (M)MIX и синтаксиса его ассемблера. Или Брюс Седжвик "Алгоритмы" - первые пол книги не понятно, то ли книга про яп Ява, то ли про алгоритмы (это несмотря на то что у него есть специально серия книг "Алгоритмы на ....").
По-этому я обеими руками за концентрацию внимания на изучаемом вопросе )))
Olej писал(а): я до безобразия не люблю книгу "Linux Device Drivers", ещё называемую в народе LDD3, на которую все ссылаются ... как будто других книг никто не видел
:-) ну это классика жанра (как кнут в алгоритмах). Раньше (лет 7 назад) тяжело вообще было подыскать качественную информацию по данной теме, ассортимент возник совсем недано. Ведь ЛДД ещё в 2005 в 3-й редакции вышел, а "Essential Linux Device Drivers" в 2008 только первая редакция, отсюда и популярность ЛДД.
Olej писал(а): «Writing Linux Device Drivers», Jerry Cooperstein, 2009
А я яй. Как я упустил этот трёхтомник? Активно интересуюсь литературой по данной тематике, но даже не знал о их существовании. Руки чешуться полистать ))) Может подскажите где найти можно? ;-)

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: проект книги: "Модули ядра Linux"

Непрочитанное сообщение Olej » 02 мар 2012, 14:29

bose писал(а):Другой пример Дон Кнут и его "Искусство программирования" - всё классно, но алгоритмы на ассемблере для виртуального (M)MIX, как для меня, выглядят не "сочно", и тяжело читаемы.
Кнут до странности "неровный": занудный 1-й том + весёленький такой ... 2-й, кажется, "получисленные алгоритмы".
bose писал(а):
Olej писал(а): я до безобразия не люблю книгу "Linux Device Drivers", ещё называемую в народе LDD3, на которую все ссылаются ... как будто других книг никто не видел
:-) ну это классика жанра (как кнут в алгоритмах). Раньше (лет 7 назад) тяжело вообще было подыскать качественную информацию по данной теме, ассортимент возник совсем недано. Ведь ЛДД ещё в 2005 в 3-й редакции вышел, а "Essential Linux Device Drivers" в 2008 только первая редакция, отсюда и популярность ЛДД.
Так лет 7 назад просто ничего другого и не было!
... ну, кроме вот этой замечательной брошюрки:
Изображение
которую совершенно по непонятным соображениям перевели "Кудиц-Образ" в 2000г. - совершенно коммерчески безумное начинание ;)
Вот она тогда мне сразу в руки и попала...
Вот эта книжка мне очень нравится, хоть и устарела сильно.
bose писал(а):
Olej писал(а): «Writing Linux Device Drivers», Jerry Cooperstein, 2009
А я яй. Как я упустил этот трёхтомник? Активно интересуюсь литературой по данной тематике, но даже не знал о их существовании. Руки чешуться полистать ))) Может подскажите где найти можно? ;-)
Мне очень повезло с этим делом:
- крупная международная софтверная компания Global Logic заказала провести занятия с их работниками...
- результатом которых и есть вот этот обсуждаемый текст...
- и надо отдать им должное: они просто по списку заказывали, оплачивали и притаскивали мне с Amazon любую запрошенную литературу... десятка 2, не менее, наименований ;)
- в библиографии в конце текста они перечислены ... ничего более серьёзного в мировых изданиях больше по этому вопросу нет, по крайней мере, по состоянию на 1 год назад.

Найти можно?
На Amazon ... это достаточно просто и дней за 15 часто они уже доставляют.
Где-то должно и электронно появляться...
... по 2-м самым интересным книгам я привёл URL, по которым лежат архивы примеров - это самое ценное, что там есть.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: проект книги: "Модули ядра Linux"

Непрочитанное сообщение Olej » 05 мар 2012, 19:26

bose писал(а):Наверное в учебных целях этим можно пренебречь, но может лучше если используются приватные данные (мод=3), то туда запихнуть переменную
Внял таки рекомендациям переделать это место :lol: ...
... но при единственном условии решил это сделать: если получится не увеличивать объём кода + не усложнять его понимание, чтобы сохранилась максимальная простота.

Кажется получилось ;-)
Думаю, что теперь это вас устроит:

Код: Выделить всё

#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include "mopen.h"

MODULE_LICENSE( "GPL" );
MODULE_AUTHOR( "Oleg Tsiliuric <olej@front.ru>" );
MODULE_VERSION( "6.4" );

static int mode = 0; // открытие: 0 - без контроля, 1 - единичное, 2 - множественное
module_param( mode, int, S_IRUGO );
static int debug = 0;
module_param( debug, int, S_IRUGO );

#define LOG(...) if( debug !=0 ) printk( KERN_INFO "! "__VA_ARGS__ )

static int dev_open = 0;

struct mopen_data {         // область данных драйвера:
   char buf[ LEN_MSG + 1 ]; // буфер данных
   int odd;                 // признак начала чтения
};

static int mopen_open( struct inode *n, struct file *f ) {
   LOG( "open - node: %p, file: %p, refcount: %d", n, f, module_refcount( THIS_MODULE ) );
   if( dev_open ) {
      LOG( "device /dev/%s is busy", DEVNAM );
      return -EBUSY;
   }
   if( 1 == mode ) dev_open++;
   if( 2 == mode ) {
      struct mopen_data *data;
      f->private_data = kmalloc( sizeof( struct mopen_data ), GFP_KERNEL );
      if( NULL == f->private_data ) {
         LOG( "memory allocation error" );
         return -ENOMEM;
      }
      data = (struct mopen_data*)f->private_data;
      strcpy( data->buf, "dynamic: not initialized!" );  // динамический буфер
      data->odd = 0;
   }
   return 0;
}

static int mopen_release( struct inode *n, struct file *f ) {
   LOG( "close - node: %p, file: %p, refcount: %d", n, f, module_refcount( THIS_MODULE ) );
   if( 1 == mode ) dev_open--;
   if( 2 == mode ) kfree( f->private_data );
   return 0;
}

static struct mopen_data* get_buffer( struct file *f ) {
   static struct mopen_data static_buf = { "static: not initialized!", 0 }; // статический буфер
   return 2 == mode ? (struct mopen_data*)f->private_data : &static_buf;
}

// чтение из /dev/mopen :
static ssize_t mopen_read( struct file *f, char *buf, size_t count, loff_t *pos ) {
   struct mopen_data* data = get_buffer( f );
   LOG( "read - file: %p, read from %p bytes %d; refcount: %d",
        f, data, count, module_refcount( THIS_MODULE ) );
   if( 0 == data->odd ) {
      int res = copy_to_user( (void*)buf, data->buf, strlen( data->buf ) );
      data->odd = 1;
      put_user( '\n', buf + strlen( data->buf ) );
      res = strlen( data->buf ) + 1;
      LOG( "return bytes :  %d", res );
      return res;
   }
   data->odd = 0;
   LOG( "return : EOF" );
   return 0;
}

// запись в /dev/mopen :
static ssize_t mopen_write( struct file *f, const char *buf, size_t count, loff_t *pos ) {
   int res, len = count < LEN_MSG ? count : LEN_MSG;
   struct mopen_data* data = get_buffer( f );
   LOG( "write - file: %p, write to %p bytes %d; refcount: %d",
        f, data, count, module_refcount( THIS_MODULE ) );
   res = copy_from_user( data->buf, (void*)buf, len );
   if( '\n' == data->buf[ len -1 ] ) data->buf[ len -1 ] = '\0';
   else data->buf[ len ] = '\0';
   LOG( "put bytes : %d", len );
   return len;
}

static const struct file_operations mopen_fops = {
   .owner  = THIS_MODULE,
   .open =    mopen_open,
   .release = mopen_release,
   .read   =  mopen_read,
   .write  =  mopen_write,
};

static struct miscdevice mopen_dev = {
   MISC_DYNAMIC_MINOR, DEVNAM, &mopen_fops
};

static int __init mopen_init( void ) {
   int ret = misc_register( &mopen_dev );
   if( ret ) { LOG( "unable to register %s misc device", DEVNAM ); }
   else { LOG( "installed device /dev/%s in mode %d", DEVNAM, mode ); }
   return ret;
}

static void __exit mopen_exit( void ) {
   LOG( "released device /dev/%s", DEVNAM );
   misc_deregister( &mopen_dev );
}

module_init( mopen_init );
module_exit( mopen_exit );

bose
Писатель
Сообщения: 107
Зарегистрирован: 23 фев 2012, 14:41
Откуда: Киев
Контактная информация:

Re: проект книги: "Модули ядра Linux"

Непрочитанное сообщение bose » 05 мар 2012, 20:07

Олег, сегодня пришёл в отчаяние. Я не буду сейчас писать много слов, о том какие эксперименты я сегодня проводил (конечно же с модулем ядра :-) ), просто задам вопрос:
В вашем примере Kexamples.144/proc/mod_procr.c приведён пример реализации функции чтения элементов в файловой системе proc. Далее цитирую с вашей книги:
Испытания:
$ make
...
$ sudo insmod ./mod_procr.ko
$ dmesg | tail -n1
module : success!
$ ls -l /proc/mod_*
-r--r--r-- 1 root root 0 Мар 26 18:14 /proc/mod_node
$ cat /proc/mod_node
Hello from module!
$ dmesg | tail -n7
module : success!
read: 3072
return bytes: 19
EOF
read: 3072
return bytes: 19
EOF
Так вот сам вопрос - почему на одну операцию чтения, происходит дважды копирования с одного буфера в другой и дважды возвращается EOF. (У меня результаты те же).

PS:
Я много чего странного заметил, эксперементируя сегодня с этим модулем. В т.ч. и то что *eof=1 если его убрать ни на что не влияет (ну ладно - 3 раза происходит копирование)...

PS2:
Я не смог найти в доступной мне литературе, описание протокола взаимодействия с этой функцией

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: проект книги: "Модули ядра Linux"

Непрочитанное сообщение Olej » 05 мар 2012, 20:31

bose писал(а):сегодня пришёл в отчаяние.
а это уже напрасно ;-)
bose писал(а): Так вот сам вопрос - почему на одну операцию чтения, происходит дважды копирования с одного буфера в другой и дважды возвращается EOF. (У меня результаты те же).
Я сначала хотел вам ответить: потому, что утилита cat делает дважды чтение...
Но потом я посмотрел чтение /dev...
И, кроме того, вы смотрите "старый" метод: (пример /mod_procr.ko), я посмотрел следующий пример (mod_proc.ko), "новый", через общую таблицу файловых операций к имени файла, там тоже 2 последовательности операций чтения, с той лишь разницей, что вместо запроса 3072 байт запрашивается 32767 - но это как раз понятно...
При том, что симметричная операция записи - вызывается однократно!

Пока не могу сказать... буду смотреть подробнее.
bose писал(а): PS:
Я много чего странного заметил, эксперементируя сегодня с этим модулем. В т.ч. и то что *eof=1 если его убрать ни на что не влияет (ну ладно - 3 раза происходит копирование)...
Странно.
А как тогда возвращается конец потока?
bose писал(а): PS2:
Я не смог найти в доступной мне литературе, описание протокола взаимодействия с этой функцией
С этой это с какой?
С:

Код: Выделить всё

ssize_t proc_node_read( char *buffer, char **start, off_t off,
                        int count, int *eof, void *data ) {
И не найдёте ;) ... мне помнится, что я какие-то оговорки где-то видел ... а вё дальше - только экспериментально, реверс-инжениринг ;).
Если я вспомню где что видел - отпишу.

А если вы посмотрите рядом с ней 2-ю, куда более загадочную функцию write_proc_t :

Код: Выделить всё

struct proc_dir_entry { 
...
        read_proc_t *read_proc; 
        write_proc_t *write_proc; 
...
}; 
- её вообще долгое время (до ядра 2.6.19?) просто не было, а read_proc_t - была...
Загадка природы?

bose
Писатель
Сообщения: 107
Зарегистрирован: 23 фев 2012, 14:41
Откуда: Киев
Контактная информация:

Re: проект книги: "Модули ядра Linux"

Непрочитанное сообщение bose » 05 мар 2012, 23:52

Olej писал(а): И, кроме того, вы смотрите "старый" метод: (пример /mod_procr.ko)
Если данный механизм остался, и он не удалён с ядра, то он должен корректно работать
Olej писал(а): Странно.
А как тогда возвращается конец потока?
Из моих "эксперементов" я понял что выводы делаются на основании смещения в странице (off). Если значение возвращаемое функцией (новое смещение) равно значению смещения переданному в функцию, то это значит что в буфер больше ничего не писалось (грубо говоря - если смещение в странице осталось неизменным на протяжении работы функции)...
В любом случае - если вы из ваших примеров уберте любые манипуляции с еоф, то результат (видимый пользователю) останется неизменным.

Всё что я сегодня "наэксперементировал", я завтра поподробнее опишу с сэмплами.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: проект книги: "Модули ядра Linux"

Непрочитанное сообщение Olej » 06 мар 2012, 00:04

bose писал(а):
Olej писал(а): И, кроме того, вы смотрите "старый" метод: (пример /mod_procr.ko)
Если данный механизм остался, и он не удалён с ядра, то он должен корректно работать
Что значит "остался"? ;)
И тот (исключительный для /proc) и другой (общий для любой fs, через таблицу операций fs) методы присутствуют одновременно, альтернативно ... имеют разные прототипы операций и разную логику вызовов.

Примеры есть и на тот (mod_procr.ko) и на другой (mod_proc.ko) методы - сравните их.

P.S. я, наверное, ошибся, когда назвал их "старый" и "новый" - они просто разные.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: проект книги: "Модули ядра Linux"

Непрочитанное сообщение Olej » 06 мар 2012, 13:07

bose писал(а): Так вот сам вопрос - почему на одну операцию чтения, происходит дважды копирования с одного буфера в другой и дважды возвращается EOF. (У меня результаты те же).
Хороший вопрос ;-)
... я, в своё время работая над этими модулями, замечал этот эффект, но не "заморачивался" с ним:
- слишком много по объёму нужно было пробежать по ядру + успевать укладываться в темп :-?
- методы то, в общем, корректно работают...
- /proc это не то место, где идёт плотный, интенсивный обмен, это не /dev, поэтому на работоспособность это не влияет...
- ... в большинстве случаев, потому что если данные ядра при последовательных чтениях будут обновляться, то здесь будет проблема :-?

Но, поскольку такое "дважды чтение" происходит и при использовании read_proc_t, и при использовании чтения через таблицу proc_fops, то можно предполагать:
- что это какая-то особая "фича" procfs ...
- потому как ни на devfs, ни на sysfs как-то ничего подобного не наблюдается? ... я не видел.

Но природу этого я постараюсь покопать.
bose писал(а): PS2:
Я не смог найти в доступной мне литературе, описание протокола взаимодействия с этой функцией
Вот в том 2-х томнике Jerry Cooperstein (а Jerry Cooperstein - участник команды Линуса Торвальдса по разработке ядра, в отличие от авторов книг LDD и ELDD) есть очень кратко и загадочно :lol: ... , но сначала прототипы на которые он ссылается, из <linux/proc_fs.h>:

Код: Выделить всё

typedef int (read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);
... у меня нет в доступе электронной копии скопировать, но для такого случая даже вручную перебью:
When someone tries to read the entry, the information will be written into page argument at an offset of off, wrining at most count bytes. For reading just a few bytes, the callback function usually ignores these arguments.

The eof argument is only used when off and count are used; it should signal the end of the file with a 1. The start argument is a left-over legacy from earlier implementation and isn't used. The data argument can be used to create a single callback function for multiple proc entryes, or for other purposes.

When successful, your read function should return the number of bytes written into the buffer pointed to by page.
Всё! Больше нигде ни слова на все 2 тома. :lol:
bose писал(а): Из моих "эксперементов" я понял что выводы делаются на основании смещения в странице (off). Если значение возвращаемое функцией (новое смещение) равно значению смещения переданному в функцию, то это значит что в буфер больше ничего не писалось (грубо говоря - если смещение в странице осталось неизменным на протяжении работы функции)...
В любом случае - если вы из ваших примеров уберте любые манипуляции с еоф, то результат (видимый пользователю) останется неизменным.
Я не подвергаю сомнению ваши эксперименты, но из его фраз:
- возврат функции - никак не смещение (не off_t), а абсолютное число обработанных байт...
- утверждается (как-то мало внятно), что за признак конца вывода отвечает eof;

Давайте разбираться дальше.

bose
Писатель
Сообщения: 107
Зарегистрирован: 23 фев 2012, 14:41
Откуда: Киев
Контактная информация:

Re: проект книги: "Модули ядра Linux"

Непрочитанное сообщение bose » 06 мар 2012, 14:01

Olej писал(а): Что значит "остался"? ;)
.....
P.S. я, наверное, ошибся, когда назвал их "старый" и "новый" - они просто разные.
Ну есть такая тендеция совместимости ради оставлять устаревшие методы и при этом помечать их deprecated (gets ;-) например)
Когда вы его обозвали "старым", я себе так и подумал )))

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: проект книги: "Модули ядра Linux"

Непрочитанное сообщение Olej » 06 мар 2012, 14:27

bose писал(а):
Olej писал(а): Что значит "остался"? ;)
.....
P.S. я, наверное, ошибся, когда назвал их "старый" и "новый" - они просто разные.
Ну есть такая тендеция совместимости ради оставлять устаревшие методы и при этом помечать их deprecated (gets ;-) например)
Когда вы его обозвали "старым", я себе так и подумал )))
Нет, здесь абсолютно нет никакого deprecated, здесь 2 альтернативных метода:
- один: специфично к именам сугубо в /proc ...
- другой: как к именами в любой файловой системе, в той же /dev ... а /proc со своим пространством имен и есть одна из любых ;)...

Интереснее другое: что в read_proc_t - половина параметров в прототипе "не используется" ... передумали :-o :lol:

Но почему в обоих случаях двухкратный вызов чтения? - для меня пока загадка...

Ответить

Вернуться в «Публикации, книги и обсуждения»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 12 гостей