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

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

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

Каждый драйвер устройства обычно управляет одним типом устройства или как максимум одним классом родственных устройств. Например, драйвер SCSI-диска обычно может управлять несколькими SCSI-дисками разного объема и разной скорости и, может быть, приводом Blu-ray-диска со SCSI-интерфейсом. А вот мыши и джойстики настолько отличаются друг от друга, что для них, как правило, требуются разные драйверы. Тем не менее технически вполне возможно создание одного драйвера устройства, управляющего несколькими разнородными устройствами. Но это в большинстве случаев не самая лучшая идея.

Но иногда совершенно разные устройства основаны на одной и той же базовой технологии. Наверное, наиболее известным примером может послужить USB — технология последовательной шины, которая не зря называется универсальной. К USB-устройствам относятся диски, карты памяти, фотоаппараты, мыши, клавиатуры, мини-вентиляторы, беспроводные сетевые карты, роботы, считыватели кредитных карт, аккумуляторные бритвы, измельчители бумаг, сканеры штрих-кодов и портативные термометры. Все они используют USB, хотя занимаются совершенно разными вещами. Характерная особенность заключается в том, что из USB-драйверов обычно формируется стек, подобный TCP/IP-стеку в сетях. Внизу, как правило, в оборудовании, находится уровень USB-ссылок (последовательного ввода-вывода), обрабатывающий все, что касается аппаратуры, например сигнализацию и декодирование потоков сигналов в USB-пакеты. Он используется для более высоких уровней, работающих с пакетами и функциями USB, общими для большинства устройств. И наконец, наверху над всем этим находятся высокоуровневые API-интерфейсы, например интерфейсы для накопителей, камер и т. д. Таким образом, у нас по-прежнему имеются отдельные драйверы устройств, несмотря на то что ими совместно используются части стека протокола.

Чтобы получить доступ к аппаратной части устройства, то есть к регистрам контроллера, драйвер устройства, как правило, должен быть частью ядра операционной системы, по крайней мере в существующих на сегодняшний день архитектурах. Но вообще-то можно создавать и драйверы, работающие в пространстве пользователя, используя при этом системные вызовы для чтения и записи регистров устройств. Такое решение позволит изолировать ядро от драйверов и драйверы друг от друга, устранив при этом основной источник системных сбоев — «сырые» драйверы, тем или иным образом мешающие работе ядра. Несомненно, это хороший выход из положения при создании высоконадежных систем. Примером системы, в которой драйверы устройств запускаются в качестве процессов пользователя, может послужить MINIX 3 (www.minix3.org). Но поскольку большинство других операционных систем для настольных компьютеров предполагают запуск драйверов в ядре, рассматриваться будет именно такая модель.

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

Рис. 5.10. Логическое позиционирование драйверов устройств. На самом деле обмен информацией между драйверами и контроллерами устройств осуществляется по шине


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

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

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

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

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

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

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

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

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

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

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

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

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

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

5.3.3.

<< | >>
Источник: Э. ТАНЕНБАУМ Х. БОС. СОВРЕМЕННЫЕ ОПЕРАЦИОННЫЕ СИСТЕМ Ы 4-е ИЗДАНИЕ. 2015

Еще по теме Драйверы устройств:

  1. Драйвер Счастья в Работе:
  2. Статья 265-1. Незаконное изготовление ядерного взрывного устройства или устройства, которое рассеивает радиоактивный материал или излучает радиацию
  3. Раздел V. Федеративное устройство
  4. § 6. Государственное устройство
  5. § 2. Форма государственного (территориально-политического) устройства
  6. § 5. Политико-территориальное устройство. Организация власти на местах
  7. Устройство мира
  8. 1.3.4. Устройство помещения
  9. § 1. Понятие и формы государственного устройства
  10. 7.4. Криминалистическое исследование взрывных устройств и взрывчатых веществ, а также следов их применения
  11. § 6. Политико-территориальное устройство. Областная автономия и местное самоуправление
  12. Глава 9. Федеративное устройство России
  13. § 6. Основы политико-территориального устройства
  14. М.Руссинович, Д.Соломон. Внутреннее устройство Microsoft Windows (главы 1–4), 2005
  15. Устройство дульного мира
  16. Устройство дульного мира
  17. § 6. Устройство детей, оставшихся без попечения родителей
  18. Богомазова Г.Н.. Установка и обслуживание программного обеспечения персональных компьютеров, серверов, периферийных устройств и оборудования, 2015