2012-05-30 3 views
22

Я разработал модуль ядра и некоторые функции на нем. Теперь мне нужно разработать программу в пользовательском пространстве и вызвать некоторые функции, которые находятся в модуле ядра.вызов функции модуля ядра из программы в пользовательском пространстве

Мне также нужно получить доступ к некоторой глобальной переменной, которая находится в модуле ядра в моей программе в пользовательском пространстве.

+0

Вы можете просто вызвать любую функцию из другого пространства. Вы можете вызвать функцию syscall или взаимодействовать через procfs или взаимодействовать с каким-либо файлом устройства, который обрабатывается вашим модулем. Можете ли вы сказать, что такое модуль? – osgx

+0

Модуль имеет некоторые функции управления сетью. Если я хочу отправить некоторые данные Ethernet, мне нужно запросить кого-то, если это возможно, используя функцию, разработанную в модуле ядра. Итак, мне нужно выполнить эту функцию, например, перед отправкой пакета. У этой функции также есть некоторые паразиты, которые мне нужно вставить. – Ricardo

ответ

23

Существует полный обзор модуля Linux-ядра и пользовательского пространства программы, взаимодействующей http://wiki.tldp.org/kernel_user_space_howto «пространства ядра, интерфейсы пользователя пространство» от Ariane Келлера (это от 2008-09-28, а около 2,6 ядра, только основные new way is relayfs) relayfs)

Не указан обычный вызов функции из пространства пользователя в пространство ядра, только syscall (добавление нового syscall нелегко) и upcall (вызов в обратном направлении).

Один из самых простых интерфейсов - ioctl; но вы не можете начать использовать ioctl перед созданием procfs, sysfs или аналогичного файла.

Прочее sysctl; но sysctl более подходит для чтения/записи глобальной переменной. (С помощью sysctl-интерфейса трудно передать несколько параметров).

+2

Я боюсь, что ссылка умерла, хотя она все еще доступна [через web.archive.org] (https://web.archive.org/web/20160214015410/http://people.ee.ethz.ch/~arkeller /linux/kernel_user_space_howto.html) – Cimbali

+1

Cimbali, спасибо. Также здесь - http://wiki.tldp.org/kernel_user_space_howto, «Ядро пространства, пользовательские пространственные интерфейсы» от Ariane Keller, 2008-10-04 – osgx

5

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

Существует только один обычный способ для пользовательской программы явно запрашивать службы из ядра - make a system call.

Есть также ловушки и некоторые механизмы связи с ядром пользователя с ядром Linux, но здесь они не актуальны.

+1

Но http: // stackoverflow.com/questions/2394985/linux-kernel-add-system-call-dynamic-through-module http://stackoverflow.com/questions/463332/is-it-possible-to-add-a-system-call-via -a-lkm - модуль не может добавить системный вызов – osgx

+5

Но он может реализовать существующий, например 'ioctl (2)'. –

+0

Ну, это не совсем так. Существуют способы изменения таблицы системных вызовов (по крайней мере, на архитектурах x86). Это связано с изменением указателя из регистра IDTR, чтобы указать на новый раздел в памяти, где существует новая таблица hysacked sys_call (произвольной длины). см. http://www.defcon.org/images/defcon-13/dc13-presentations/dc-13_grizzard.pdf для общей идеи атаки. – ajpyles

5

Как и другие плакаты уже упоминалось, существует четкое различие между ядро и пользовательское пространство. Таким образом, вы не можете вызвать функцию ядра непосредственно из пользовательского пространства. Я думаю, что самый простой способ отправить сообщения между пользовательским пространством и пространством ядра - через сокеты netlink. Сетевой сокет позволяет легко передавать произвольные структуры данных между уровнем пользователя и уровнем ядра.

Да, ioctl, системные вызовы являются жизнеспособными альтернативами, они не так гибки, как сокет netlink для передачи произвольной информации.

Пример кода здесь: http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-3.html

+0

Просто примечание: код нуждается в следующих незначительных изменениях, чтобы заставить его работать на более новых ядрах: изменить следующая строка в gnKernel.c: rc = genlmsg_unicast (skb, info-> snd_pid); до rc = genlmsg_unicast (genl_info_net (info), skb, info-> snd_pid); Ядро, которое я тестировал, было 2.6.35-22-generic – lithiumhead

Смежные вопросы