Выполнение функции пространства пользователя из пространства ядра

Я пишу собственный драйвер устройства в Linux, который должен очень быстро реагировать на прерывания. Код для обработки этого уже существует в реализации пользовательского пространства, но он слишком медленный, поскольку полагается на программное обеспечение, постоянно проверяющее состояние линии прерывания. Проведя некоторые исследования, я обнаружил, что вы можете зарегистрировать эти строки прерываний из модуля ядра и выполнить функцию, заданную указателем на функцию. Однако код, который мы хотим выполнить, находится в пользовательском пространстве, есть ли способ вызвать функцию в пользовательском пространстве из модуля пространства ядра?

4 ответа

Решение

Вам не повезло с вызовом функций пользовательского пространства из ядра, поскольку ядро ​​не знает и не должно знать об отдельных функциях и логике приложений пользовательского пространства, не говоря уже о том, что каждое приложение пользовательского пространства имеет свою собственную память компоновка, так что ни одному процессу, ни ядру не разрешается вторгаться таким образом (разделяемые объекты здесь исключение, но вы все равно не можете использовать это из пространства ядра). Что касается модели безопасности, вы не должны запускать код пользовательского пространства (который автоматически считается небезопасным кодом в контексте ядра) в первую очередь в контексте ядра, так как это нарушит модель безопасности ядра прямо в это мгновение Теперь, учитывая все вышеперечисленное, а также многие другие мотивы, вы можете пересмотреть свой подход и сосредоточиться на Kernel <-> IPC и интерфейсах пользовательского пространства, файловой системе или вспомогательном API пользовательского режима (читайте ниже).

Вы можете вызывать приложения из пространства пользователя из ядра, которые используют API usermode-helper. Следующая статья IBM DeveloperWorks поможет вам начать использовать API ядра Linux usermode-helper:

API ядра: Часть 1. Вызов приложений из пользовательского пространства из ядра.

Я думаю, что самый простой способ - зарегистрировать символьное устройство, которое становится готовым, когда на устройстве есть какие-то данные.

Любой процесс, который пытается прочитать данные с этого устройства, затем переводится в спящий режим, пока устройство не будет готово, а затем пробуждается, и в этот момент он может сделать соответствующую вещь.

Если вы просто хотите сообщить о готовности, читатель может просто прочитать один нулевой байт.

В этом случае пользовательская программа просто должна будет выполнить блокирующий вызов read() и будет соответствующим образом заблокирована, пока вы не проснетесь.

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

Похоже, ваша линия прерываний уже доступна пользователям через gpiolib? (/ SYS / класс / GPIO /...)

Вы тестировали, достаточно ли быстр для запуска gpio edge и poll()? Таким образом, вам не нужно опрашивать статус из приложения пользовательского пространства, но запуск по фронту сообщит об этом через poll(). Смотрите Documentation/gpio.txt в исходном коде ядра.

Если запуск по фронту через sysfs недостаточно хорош, то правильным способом является разработка драйвера ядра, который заботится о критичной ко времени части и экспортирует результаты в пространство пользователя через API (sysfs, узел устройства и т. Д.).

Я также сталкиваюсь с той же проблемой, я прочитал этот документ http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-6.html, поэтому планирую использовать сигналы. В моем случае нет шансов потерять сигналы, потому что
1. система замкнута, после сигналов, только я получу другой сигнал.
2. И я использую сигналы реального времени POSIX.

Другие вопросы по тегам