Функционирование драйверов устройств


Драйвер устройства выполняет несколько функций:

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

Инициализацию устройства.

Управление энергопотреблением устройства и регистрацией событий.

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

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

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

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

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

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

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

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

Главный вопрос операционной системы — как сделать так, чтобы все устройства ввода-вывода и драйверы выглядели примерно одинаково. Если диски, принтеры, клавиатуры и т. д. требуют различных интерфейсов, то при появлении нового устройства будет требоваться переделка операционной системы, что естественно очень неудобно.

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

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

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

С именованием устройств тесно связан вопрос защиты. Как ОС предотвращает доступ пользователей к устройствам, на который у них нет прав? В UNIX и в Windows 2000 устройства представляются в файловой системе в виде именованных объектов, что дает возможность применять обычные правила защиты файлов к устройствам ввода-вывода. Системныйадминистратор может установить нужные разрешения для каждого устройства.