Иллюстрированный самоучитель по теории операционных систем

Сервисы ядра, доступные драйверам

Следует провести различие между системными вызовами и функциями ядра, доступными для драйверов. Наборы системных вызовов и драйверных сервисов совершенно независимы друг от друга. Как правило, системные вызовы недоступны для драйверов, а драйверные сервисы – для пользовательских программ.

Системный вызов включает в себя переключение контекста между пользовательской программой и ядром. В системах с виртуальной памятью во время такого переключения процессор переходит из "пользовательского" режима, в котором запрещены или ограничены доступ к регистрам диспетчера памяти, операции ввода-вывода и ряд других действий, в "системный", в котором все ограничения снимаются. Обычно системные вызовы реализуются с использованием специальных команд процессора, чаше всего – команды программного прерывания.

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

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

Сервисы, доступные для обработчиков прерываний, должны удовлетворят двум требованиям: они должны быть реентерабельными и завершаться за гарантированное время. Например, выделение памяти может потребовать сборки мусора или даже поиска жертвы для удаления в адресных пространствах пользовательских задач. Кроме того, выделение памяти требует работы с разделяемым ресурсом (пулом памяти ядра) и его достаточно сложно реализовать реентерабельным образом, поэтому обработчикам прерываний очень редко разрешают запрашивать память.

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

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

  • Взаимодействие с конфигурацией системы – доступ к данным средств автоконфигурации и, кроме того, регистрация драйвера и управляемых им устройств в системе.
  • Сбор и сохранение статистики.
  • Запросы на выделение и освобождение системных ресурсов, в первую очередь памяти.
  • Примитивы межпоточного взаимодействия – между нитями самого драйвера, между драйвером и другими нитями ядра и, наконец, между драйвером и нитями пользовательского процесса.
  • Таймеры.
  • Передача данных из пользовательского адресного пространства и обратно и другие операции над пользовательским адресным пространством.
  • Сервисные функции.

Некоторые из групп этих функций будут подробнее описаны далее.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.