[quote=Olej]
[quote=drBatty]
Можно ли в модуле выполнить те же функции, что и в пользовательской программе? А именно: открыть файл
Вопрос хороший и ответ на него не очевидный...[/quote]
[/quote]
Здесь я ошибся!
Действительно, единственный умный пост в теме написал nihao, а не drBatty.
drBatty написал:
раз уж вы меня обвиняете в неграмотности.)
А неграмотность? при чём тут обвинения? - неграмотность она либо есть, либо её нет :lol: - это как с сусликом :lol:
drBatty написал:
Вы в игноре.
Наконец то!
Теперь хоть предмет темы пообсуждать можно - никто под ногами не путается.
... а для вас, drBatty, есть там рядом немало более доступных тем: игры там ... мультимедии разные, опять же wink
А именно: открыть файл (не файл устройства! не в /proc) и прочитать данные оттуда в свой собственный буфер
Для однозначности терминологии: при работе с именами из /proc и из /dev со стороны модуля - ничего подобного "открытию" и т.п. операциям не делается, там а). совсем другие механизмы б). и совсем специальный набор API для этого, в). причём, для /proc - один API, а для /dev - совершенно другой, ... а для /sys - ещё свой отдельный API.
Это всё совершенно отдельные темы, и с чтением файла они просто не имеют ничего минимально общего!
[quote=Olej] а вот запустить в пользовательское пространство новое приложение как exec() модуль элементарно может
как exec модуль уж точно не может. man 3 exec для закрепления.[/quote]
Fat-Zer, вы сами себе противоречите:
- ... только для лучшего закрепления лучше всё-таки :D
text
$ man 2 execve
- потому как все библиотечные вызовы execl, execlp, execle, execv, execvp - тут же сразу транзитом преобразуются в системный вызов execve ...
- который тоже ничего сам не делает, а тут же превращается в int 80h (или sysenter, если вам так больше нравится wink - что в точности то же самое)... и мы уже в kernel
- ничего более (т.е. практически ничего вообще) в пользовательском процессе не делается, не происходит.
- если exec из пользовательского процесса создаст новый процесс только и полностью в вызове кода kernel - то почему же сам код kernel не может делать то же самое?
- а код модуля ничем(!) не отличается от кода самого ядра (в чём и есть самое слабое место всей этой модели).
Ну так почему бы коду модуля ядра не запускать ещё новый пользовательский процесс?
И кто тогда вообще запускает для вас всё множество пользовательских процессов, когда вы набираете команды в shell? :lol:
Обычный файл из ядра читать может трудно, а может и невозможно
из ядра возможно !ВСЁ!, что не запрещено запрещено законами физики и математики.
про exec: был тонкий намёк на фундаментальное свойство:
The exec() family of functions replaces the current process image with a new process image.
что для работы в режиме ядра - бред. или вы предлогаете любой current заменять? это можно, но смысла в этом не больше, чем в чтение файла... всегда сделать /dev/leper_colony и всякого, кто будит читать или писать заменять на /bin/leper и через некоторое количество времени убивать его. wink
Olej написал:
Ну так почему бы коду модуля ядра не запускать ещё новый пользовательский процесс?
а это пожалуйста...
ещё раз: из ядра можно сделать \практически\ ВСЁ(!)
ЗЫ: Olej, drBatty, балаган без переписки по сабжу прекращаем...
[quote=Olej]Вы покажите как читать - и всё станет, может, не так трудно?
да элементарно.... собрать самостоятельно сможете...
[/quote]
Пример хорош (мне было интересно).
Это и есть то, что я просил показать: простенько и со вкусом wink
По нему как раз можно кой-чего прокомментировать в пояснение первоначального вопроса ... но я это сделаю чуть позже.
Можно ли в модуле выполнить те же функции, что и в пользовательской программе?
Конечно же нельзя!
Можно использовать некоторый только по смыслу похожий набор вызовов из kernel API (если такой набор существует для ваших целей!).
Вот Fat-Zer использовал набор функций filp_open() -> kernel_read() -> filp_close(), что по смыслу похоже на open() - read() - close(), но это совершенно другие API! (они даже расположены в совершенно разных местах-адресах open() - read() - close() в libc.so, а filp_open() - kernel_read() - filp_close() в kernel).
P.S. пример, конечно подкупающий своей простотой, ... я, конечно, собрал, поигрался wink ... респект...
единственно, вызывает сомнение место (т.е. я просто не согласен):
text
filp_close( f, current->files );
- использование current внутри модуля, загружаемого insmod (в функции инициализации)??? - ну и на чью структуру task будет указывать такой curent?
вполне достаточно:
text
filp_close( f, NULL );
Я когда-то решал подобную задачу по-другому, другой набор kernel API, он несколько более общий, но сложнее и более громоздкий. Для полноты картины я переписал "в том стиле" показанный пример (с теми же переменными), получилось вот что:
А привёл я другой вариант вот почему:
- здесь использован другой набор kernel API: filp_open() -> vfs_llseek() -> vfs_read() -> filp_close() ...
- который только похож на набор POSIX API userspace по своему смыслу...
- и использованы прямые вызовы экспортируемых имён модуля VFS ... и так во всём: в коде доступны только те имена kernel API, которые экспортируются либо самим ядром, либо подгруженными модулями...
- а сверх того (сверх возможностей предоставленных таким экспортом) ничего в коде модуля получить нельзя... (как например, ту же таблицу sys_call_table, которую уже не раз упоминали).
про exec: был тонкий намёк на фундаментальное свойство:
The exec() family of functions replaces the current process image with a new process image.
что для работы в режиме ядра - бред. или вы предлогаете любой current заменять? это можно, но смысла в этом не больше, чем в чтение файла... всегда сделать /dev/leper_colony и всякого, кто будит читать или писать заменять на /bin/leper и через некоторое количество времени убивать его. wink
Olej написал:
Ну так почему бы коду модуля ядра не запускать ещё новый пользовательский процесс?
а это пожалуйста...
ещё раз: из ядра можно сделать \практически\ ВСЁ(!)
Я здесь не уловил смысла рассуждений, зачем это сказано? :
- exec() в POSIX, вообще то не создаёт нового адресного пространства, для него это делает всегда предшествующий fork() (в Win32 там, как помнится, картина другая ... с точностью до наоборот wink )
- так точно и kernel при использовании helper-API - создаёт ещё одно адресное пространство (юзеровское), и после создаёт в нём процесс.
- использование current внутри модуля, загружаемого insmod (в функции инициализации)??? - ну и на чью структуру task будет указывать такой curent?
вполне достаточно:
копипастил из close() - не задумывался, что там во втором параметре. а вообще стоит посмотреть что это такое....
vfs_read напрямую лучше не использовать. он рассчитан на то, что буфер находится в юзерспейсе. ИРЛ разницы наверняка не будет, но правильнее использовать обёртку. (хотя там какая-то тёмная фигня происходит)
vfs_read напрямую лучше не использовать. он рассчитан на то, что буфер находится в юзерспейсе. ИРЛ разницы наверняка не будет, но правильнее использовать обёртку. (хотя там какая-то тёмная фигня происходит)