Вы здесь

Драйверы Устройств

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

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

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

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

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

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

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

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

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

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

2) инициализацию устройства;

3) управление энергопотреблением устройства и регистрацией событий;

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

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

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

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

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

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

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

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

Предмет: