Сервисы ядра доступные драйверам
Сервисы ядра, доступные драйверам
Следует провести различие между системными вызовами и функциями ядра, доступными для драйверов. Наборы системных вызовов и драйверных сервисов совершенно независимы друг от друга. Как правило, системные вызовы недоступны для драйверов, а драйверные сервисы — для пользовательских программ.
Системный вызов включает в себя переключение контекста между пользовательской программой и ядром. В системах с виртуальной памятью во время такого переключения процессор переходит из "пользовательского" режима, в котором запрещены или ограничены доступ к регистрам диспетчера памяти, операции ввода-вывода и ряд других действий, в "системный", в котором все ограничения снимаются. Обычно системные вызовы реализуются с использованием специальных команд процессора, чаше всего — команды программного прерывания.
Драйвер же исполняется в "системном" режиме процессора и, как правило, в контексте ядра, поэтому для вызова сервисов ядра драйверу не надо делать никаких переключений контекста. Практически всегда такие вызовы реализуются обычными командами вызова подпрограммы.
Еще одно важное различие состоит в том, что, исполняя системный вызов, программисту не надо заботиться о его реентерабельности: ядро либо обеспечивает подлинную реентерабельность, либо создает иллюзию рентабельности благодаря тому, что исполняется с более высоким приоритетом, чем все пользовательские программы. Напротив, доступные драйверам сервисы ядра делятся на две группы — те сервисы, которые можно вызывать из обработчиков прерываний и те, которые нельзя.
Сервисы, доступные для обработчиков прерываний, должны удовлетворят двум требованиям: они должны быть реентерабельными и завершаться за гарантированное время. Например, выделение памяти может потребовать сборки мусора или даже поиска жертвы для удаления в адресных пространствах пользовательских задач. Кроме того, выделение памяти требует работы с разделяемым ресурсом (пулом памяти ядра) и его достаточно сложно реализовать реентерабельным образом, поэтому обработчикам прерываний очень редко разрешают запрашивать память.
Копирование данных между пользовательским и системным адресными пространствами может привести к возникновению страничного отказа, время обработки которого может быть непредсказуемо большим.
Далее, для краткости, мы будем называть доступные для обработчиков прерываний сервисы реентерабельными, хотя для них важна не только реентерабельность, но и завершение в течение фиксированного времени. В предыдущих разделах мы упоминали некоторые категории сервисов, предоставляемых драйверам. Эти сервисы включают в себя (приведенный список не является исчерпывающим) следующие.
- Взаимодействие с конфигурацией системы — доступ к данным средств автоконфигурации и, кроме того, регистрация драйвера и управляемых им устройств в системе.
- Сбор и сохранение статистики.
- Запросы на выделение и освобождение системных ресурсов, в первую очередь памяти.
- Примитивы межпоточного взаимодействия — между нитями самого драйвера, между драйвером и другими нитями ядра и, наконец, между драйвером и нитями пользовательского процесса.
- Таймеры.
- Передача данных из пользовательского адресного пространства и обратно и другие операции над пользовательским адресным пространством.
- Сервисные функции.
Некоторые из групп этих функций будут подробнее описаны далее.