Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
asddfsd Гость
|
Добавлено: Пн Июл 07 2003 13:36 Заголовок сообщения: Обработка прерываний из пользовательской программы |
|
|
Народ подскажите, если кто знает, в чем разница между контекстом ядра и контекстом прерываний? И как эту разницу, по возможности обойти.
Мне нужно из обработчика прерываний драйвера выполнять функцию, которая находится в коде пользовательской программы, открывшей драйвер. Перепробывал все, о чем в книжках по обработке прерываний в Linux написано и ненаписано(жесткие, мягкие прерывания, по планировщику таймера and more). Когда обработчик пытается вызвать пользовательскую функцию, ядро конкретно в панике падает, после чего помагает тока reset. К вопросу, который был в самом начеле. Если вызывать пользовательскую функцию просто из кода драйвера (из ioctl или т.п.), то все чики-пики работает. |
|
Вернуться к началу |
|
|
asddfsd Гость
|
Добавлено: Пн Июл 07 2003 13:40 Заголовок сообщения: ОС |
|
|
Все ето дело под Linux |
|
Вернуться к началу |
|
|
Dmitry.Karpov http://prof Гость
|
Добавлено: Пн Июл 07 2003 19:37 Заголовок сообщения: Думаю, надо освободитть прерывание |
|
|
Пока обработчик прерывания не освободит его, никакие прерывания выполняться не могут. Соотвественно, в режим задачи переходить нельзя.
А можно ли написать так, что обработчик заканчивает работу, возвращая вызвавшей его программе инструкцию о том, какую процедуру вызвать? |
|
Вернуться к началу |
|
|
asddfsd Гость
|
Добавлено: Вт Июл 08 2003 09:53 Заголовок сообщения: Re: Думаю, надо освободитть прерывание |
|
|
В целом я понял, но проблема вроде как становится неразрешимой (без изменения ядра). Хотя несовсем понятно, почему просто из кода драйвера (например из ioctl или read) можно выпонять пользовательские функции, а из обработчика прерываний нет. Я продположил, что память процесса пользователя является своппируемой и линукс это контролирует. Т.е. попытка прыгнуть на код, которого нет в ОП, приводит к необходимости подгрузить последний с HDD, а это требует аппаратных прерываний, которые не могут произойти, потому как незавершилась обработка предыдущего прерывания. Я пробую в обработчике прерываний создавать новый отложенный процесс, который и должен вызывать пользовательскую функцию уже не в контексте прерываний, но пока тоже не работает. Может делаю что то не то, вероятно создаваемый процесс работает не вконтексте ядра, а в своем собственном, а потому и проблемы. Т.е. нужно наверное в режиме ядра переодически вызывать какую то функцию, которая и будет вызывать пользовательскую процедуру.
Что касается твоего вопроса, то так сделать можно (по сигналам или просто если пользовательская программа будет опрашивать состояние драйвера), но это будет довольно медленно и немного не то. В этом случае в прикладной задаче должен быть соответствую щий анализирующий код и т.п. А если драйвер будет вызывать процедуру, то от прикладной программы требуется тока указать драйверу какую функцию и, возможно, при каких условиях вызывать. |
|
Вернуться к началу |
|
|
Борис Гость
|
Добавлено: Вт Июл 08 2003 18:50 Заголовок сообщения: Моя интерпретация Баховской "Архитектуры..." без претензий на абсолютную истинность. |
|
|
Пусть есть прикладной процесс (А) и системный процесс (Б). В общем работа выполняется следующим порядком: --процесс А (имеет прикладные привилегии и может породить новый процесс с прикладными привилегиями) вызывает системную функцию; --системная функция продолжает процесс А в виде процесса Б или порождает новый процесс Б, в обоих случаях появляется процесс Б; --процесс Б (имеет системные привилегии, но реализован так, что перед выполнением заданных действий понижает свои привилегии до прикладных, в этот момент он может породить новый процесс с прикладными привилегиями) понижает привилегии до уровня прикладных; --процесс Б вызывает прерывание (то есть выполняет само действие), прерывание -- это такая операция, у которой нельзя понизить привилегии -- у неё нет вообще понятия привилегия, это непосредственно запрошенное действие. Но из-за этого (из-за того, что это непосредственно действие) прерывание по сути исполняется с наивысшими привилегиями. В юниксе таким действиям запрещено порождать другие (непривилегированные) процессы. За этим следит даже не система, а ЦПУ. Если бы прерываниям было разрешено порождать прикладные (а не системные, то есть находящиеся в коде операционной системы), то прикладной процесс, вызванный из прерывания, получил бы системные привилегии. А это есть нулевая безопасность, как в обычном понимании (в смысле НСД), так и в отношении устойчивой работы системы, так как прикладной процесс может захватить управление. Что мы и видим:
>>> Когда обработчик пытается вызвать пользовательскую функцию, ядро конкретно в панике падает
Обработчик-то согласен вызвать функцию (ты его вынуждаешь, написав таким образом программу), но эта функция несистемная, и ЦПУ её гасит. А ЦПУ в подавляющем большинстве случаев некорректные действия игнорирует и двигает к следующей инструкции. И это инструкция в таком контексте скорее всего бессмыслена, вот и начинается исполнение бессмысленного кода, которое выглядит как зависание.
Но спрашивается, почему
>>> Если вызывать пользовательскую функцию просто из кода драйвера (из ioctl или т.п.), то все чики-пики работает.
Ответ такой: код драйвера перед исполнением пользовательской функции понижает привилегии, и не возникает конфликта по привилегиям.
Уф, ничего не сказал, как и что делать, но надеюсь, что разъяснил, почему не работает. И надеюсь, что разъяснение поможет сделать, чтобы работало. |
|
Вернуться к началу |
|
|
trtreer Гость
|
Добавлено: Ср Июл 09 2003 09:35 Заголовок сообщения: Спасибо, в теории все более или менее разъяснилось |
|
|
Но, должно както заработать!!!? Я делал такую вещь. В обработчике прерываний просто устанавливал признак, что прерывание было. Параллельно в коде драйвера порождался таймер (через системные сервисы), который переодически опрашивает этот признак, и если он установлен,то таймерная функция драйвера вызывает пользовательскую функцию и сбрасывала признак прерывания. Все равно ядро падает. Возможно причины те же, что и с обработчиком прерываний, или я неправильна создавал таймер. Хотя если по таймеру не вызывать пользовательскую функцию, то все работает.? |
|
Вернуться к началу |
|
|
|