Создание модуля ядра линукс и програмки к этому модулю.

Вопросы программного кода и архитектуры Linux

Модератор: Olej

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

Re: Создание модуля ядра линукс и програмки к этому модулю.

Непрочитанное сообщение Olej » 29 авг 2022, 00:09

Olej писал(а):
29 авг 2022, 00:03
Вот как это теперь работает:
Но!
Я сразу не сообразил, по задаче - но цикл <сообщения+пауза> нельзя запустить в инициилизирующей функции, или из неё вызвать функцию цикла... :oops:
Из инициализирующей функции proc_init() модуля нужно запускать отдельный поток ядра, а ему уже передавать функцию бесконечного цикла...
А в функции выгрузки модуля proc_exit() нужно корректно завершить этот отдельный поток!

Так что пока это - только пол-дела. :-o :roll:

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

Re: Создание модуля ядра линукс и програмки к этому модулю.

Непрочитанное сообщение Olej » 29 авг 2022, 01:34

Olej писал(а):
29 авг 2022, 00:09
Из инициализирующей функции proc_init() модуля нужно запускать отдельный поток ядра, а ему уже передавать функцию бесконечного цикла...
А в функции выгрузки модуля proc_exit() нужно корректно завершить этот отдельный поток!
1). Это совсем не такое простое дело...
2). Но интересное...
Поэтому 1) + 2) - сделал такой модуль.
P.S. Это вам как вариант ... Вы можете поэкспериментировать и сделать лучше.
Вот как это работает:
- Загрузка:

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

$ sudo insmod mod_loop.ko period=10

$ dmesg | tail -n4
[39765.110729] ! /proc/mod_loop directory created
[39765.110734] ! /proc/mod_loop/period created
[39765.111051] !! thread 26911l is running
[39765.111053] !! [4334434560] Hello fron module!
:lol: :-o ... я вместо from в выводе написал fron ... но это поправимо :oops:

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

$ cat /proc/mod_loop/period
10

$ dmesg | tail -n7
[39765.110734] ! /proc/mod_loop/period created
[39765.111051] !! thread 26911l is running
[39765.111053] !! [4334434560] Hello fron module!
[39775.606061] !! [4334445056] Hello fron module!
[39783.855500] ! return 2 bytes: <10>
[39783.855533] ! return EOF
[39785.845508] !! [4334455296] Hello fron module!
По меткам времени хорошо видно период 10 сек.

- Поменяли период на ходу:

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

$ echo 20 > /proc/mod_loop/period

$ cat /proc/mod_loop/period
20

$ dmesg | tail -n7
[39826.803296] !! [4334496256] Hello fron module!
[39828.006697] ! write: 2 bytes - 20
[39831.319768] ! return 2 bytes: <20>
[39831.319798] ! return EOF
[39837.042731] !! [4334506496] Hello fron module!
[39857.521630] !! [4334526976] Hello fron module!
[39878.000528] !! [4334547456] Hello fron module!
По меткам времени хорошо видно период 20 сек.

- Выключаем:

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

$ sudo rmmod mod_loop.ko0

$ dmesg | tail -n7
[39857.521630] !! [4334526976] Hello fron module!
[39878.000528] !! [4334547456] Hello fron module!
[39898.479410] !! [4334567936] Hello fron module!
[39918.958315] !! [4334588416] Hello fron module!
[39939.437194] !! [4334608896] thread 26911l finished
[39939.437225] ! [4334608896] child thread finished
[39939.437236] ! /proc/mod_loop/period removed
Хорошо видно:
- завершение рабочего потока...
- модуль ожидает завершения потока - синхронизация по завершению...
- завершение происходит довольно долго - пока закончится текущий цикл потока...
- только после этого выгружается модуль.
Вложения
fops_rw.c
(1020 байт) 28 скачиваний
mod_loop.c
(2.32 КБ) 28 скачиваний

PaiMeiPetrovich
Писатель
Сообщения: 36
Зарегистрирован: 26 авг 2022, 20:56
Контактная информация:

Re: Создание модуля ядра линукс и програмки к этому модулю.

Непрочитанное сообщение PaiMeiPetrovich » 29 авг 2022, 06:36

Ух тыы! Спасибо огромное! Сейчас буду разбираться с кодом! Я и первый вариант скачаю и 2-й, чтобы разницу прочувствовать и понять. Идея, с потоком, кстати, у меня мелькнула в голове (делал проект "философы", там создавал поток, следящий за философом, чтобы тот вовремя "успевал покушать" (получал доступ к данным каждые пару секунд) и не умирал.) потому что интуитивно хочется вынести функцию цикла из module_init, а то как-то некрасиво чтоли...

PaiMeiPetrovich
Писатель
Сообщения: 36
Зарегистрирован: 26 авг 2022, 20:56
Контактная информация:

Re: Создание модуля ядра линукс и програмки к этому модулю.

Непрочитанное сообщение PaiMeiPetrovich » 29 авг 2022, 09:15

Вопросы по коду!
По функции "mod_loop.c"
1)Как период (static uint period = 5) записывается в файл /proc/mod_loop/period? Вообще не понимаю, как это произошло! :-( ( даже не могу найти строчки в коде. где это могло бы быть!)
2)Что за флаг завершения и зачем он нужен? Это благодаря нему происходит синхронизация? (То есть, выгрузка модуля происходит не сразу, а дожидается завершения текущей итерации цикла благодаря именно этому флагу?)
3)Что за "task_struct"? Обязательным ли условием запуска потока является создание структурки "task_struct"?
Сам тоже начну искать ответы на эти вопросы (на первый вопрос точно не найду ответа)

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

Re: Создание модуля ядра линукс и програмки к этому модулю.

Непрочитанное сообщение Olej » 29 авг 2022, 10:32

PaiMeiPetrovich писал(а):
29 авг 2022, 06:36
потому что интуитивно хочется вынести функцию цикла из module_init, а то как-то некрасиво чтоли...
Дело не в том что некрасиво :lol: ...
Если вы вызовете функцию цикла из proc_init (инициализации), то это будет выглядеть так, что при загрузке командой insmod - команда "зависнет" на выполнении пока не завершится цикл. А нам нужно чтобы инициализация завершилась, а цикл продолжил выполняться.

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

Re: Создание модуля ядра линукс и програмки к этому модулю.

Непрочитанное сообщение Olej » 29 авг 2022, 10:36

PaiMeiPetrovich писал(а):
29 авг 2022, 09:15
Что за "task_struct"?
Это и есть структура соответствующая каждому потоку в системе.
Причём, что интересно, такая структура создаётся (соответствует) каждому потоку в системе - хоть потоку ядра, хоть потоку пользовательского приложения, а значит и главному потоку любого процесса. И все они, такие task_struct, включаются в один связный циклический список внутри ялра.

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

Re: Создание модуля ядра линукс и програмки к этому модулю.

Непрочитанное сообщение Olej » 29 авг 2022, 10:47

PaiMeiPetrovich писал(а):
29 авг 2022, 09:15
2)Что за флаг завершения и зачем он нужен? Это благодаря нему происходит синхронизация? (То есть, выгрузка модуля происходит не сразу, а дожидается завершения текущей итерации цикла благодаря именно этому флагу?)
1). когда затребована выгрузка модуля (rmmod) proc_exit() не может просто так взять и остановить выполняющийся поток...
2). он через kthread_stop() сигнализирует потоку: "пора заканчиваться"...
3). поток видит это через kthread_should_stop() и завершается тогда, когда он может это сделать (в данном случае после истечения времени текущего цикла)
4). proc_exit() не имеет права завершать модуль до окончания завершающегося потока ... и ждёт этого на wait_for_completion()
5). поток сигнализирует что он готов завершаться (вот-вот завершится) через complete()...
6). ... делает это он через "флаг" типа struct completion

Т.е. заквершить всё это хозяйство гораздо сложнее, чем запустить. :lol:

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

Re: Создание модуля ядра линукс и програмки к этому модулю.

Непрочитанное сообщение Olej » 29 авг 2022, 10:57

PaiMeiPetrovich писал(а):
29 авг 2022, 09:15
1)Как период (static uint period = 5) записывается в файл /proc/mod_loop/period? Вообще не понимаю, как это произошло! :-( ( даже не могу найти строчки в коде. где это могло бы быть!)
1). команда: echo 20 > /proc/mod_loop/period - выполняет fd=open("/proc/mod_loop/period", ...) и затем write(fd, "20", ...)
2). модуль, через таблицу операций node_fops (позиция node_write) вызывает функцию node_write()
3). строка "20" переданная write() копируется из пространства пользователя в buf_msg в пространстве ядра...
4). строка "20" преобразуется в число 20 - simple_strtoul()
5). если число значимое (>0) (т.е. write() не писало мусор, не числовое значение), то новое знвчение присваивается period.
Всё. :lol:

PaiMeiPetrovich
Писатель
Сообщения: 36
Зарегистрирован: 26 авг 2022, 20:56
Контактная информация:

Re: Создание модуля ядра линукс и програмки к этому модулю.

Непрочитанное сообщение PaiMeiPetrovich » 29 авг 2022, 11:25

Olej писал(а):
29 авг 2022, 10:47
поток видит это через kthread_should_stop()
У меня как раз созрел вопрос по этому поводу, но вы на него уже дали ответ! :-D
Но есть еще кое-что...
while(!kthread_should_stop())...
То есть, эта функция возвращает NULL (или 0) постоянно, но она ждет сигнала от kthread_stop(). Как только этот сигнал получен, эта ф-ия возвращает значение, отличное от нуля и привет!(цикл завершается)

PaiMeiPetrovich
Писатель
Сообщения: 36
Зарегистрирован: 26 авг 2022, 20:56
Контактная информация:

Re: Создание модуля ядра линукс и програмки к этому модулю.

Непрочитанное сообщение PaiMeiPetrovich » 29 авг 2022, 11:28

В общем, когда вы перевели на человеческий язык, стало гораздо понятнее. Я попробую по аналогии сделать так, чтобы модуль реагировал на изменение имени файла, куда записывать строки. Ну и...Код культурно оформить, дабы ваши глаза не рябило от моего кода... :-)

Ответить

Вернуться в «Linux изнутри»

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

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