Модули ОС, которые осуществляют трансляцию однотипных для всех устройств обращений к ним из процессов и из других модулей ОС в специфические для устройства управляющие воздействия и управляют выполнением этих воздействий, называются драйверами.
Каждому типу устройства соответствует свой драйвер. Драйвер устройства имеет два основных уровня. Первый (верхний) уровень принимает системные вызовы от процессов и формирует на основании каждого вызова запрос. Этот же уровень выстраивает запросы в очередь и поддерживает упорядоченность этой очереди в соответствии с принятой дисциплиной обслуживания. Второй (нижний) уровень драйвера выбирает из очереди первый запрос и обслуживает его: формирует управляющие воздействия и передает их на устройство, обрабатывает прерывания от устройства и сообщает ядру ОС о наступлении событий, связанных с вводом-выводом.
Хотя в современных системах предпочтение отдается именно древовидной структуре подключения, возможна и более сложная структура, допускающая подключение устройства к нескольким контроллерам, а контроллера - к нескольким каналам. Реальный адрес устройства может формироваться, таким образом, динамически. В недревовидной структуре подключения возможна как симметричная конфигурация (все устройства подключены ко всем контроллерам, все контроллеры - ко всем каналам), так и несимметричная. В последнем случае выбор траффика усложняется.
Для принятия решений о доступности устройств ОС поддерживает таблицы дескрипторов, отражающие состояние станций траффика (три таблицы - по числу типов станций). Для канала дескриптор включает в себя: идентификатор канала; состояние (занят/свободен); список
контроллеров, подключенных к каналу; список запросов к каналу. Для контроллера: идентификатор контроллера; состояние; список каналов, к которым подключен контроллер; список устройств, подключенных к контроллеру; список запросов к контроллеру. Для устройства: идентификатор устройства; состояние; список контроллеров, к которым подключено устройство; список запросов к устройству.
Логически являясь частью ОС, драйверы, тем не менее оформляются как отдельные модули. Поскольку каждый драйвер однозначно связан с устройством определенного типа (а возможно, и данной модификации), то и состав набора драйверов зависит от конфигурации аппаратных средств. Кроме того, обязательно должна быть обеспечена возможность подключения к системе новых внешних устройств без внесения изменений в ОС. При модульности драйверов это достигается простым добавлением нового драйвера к системному программному обеспечению. Драйверы загружаются в память либо при загрузке системы, либо (реже) - динамически, при возникновении потребности в них. Выбор драйверов для загрузки выполняется либо по явным указаниям в процедуре инициализации ОС (OS/2), либо неявно - по имеющимся таблицам конфигурации системы (VM/ESA, MVS/ESA) либо полностью автоматически - путем опроса при загрузке всех установленных устройств, опознания их и подключения соответствующих драйверов. Последний принцип получил название plug and play (включил и играй).
Примеры драйверов устройств:
Приводимые ниже примеры показывают, что на драйверы некоторых устройств часто возлагаются дополнительные функции помимо непосредственного управления вводом-выводом.
Драйвер системных часов. Вычислительные системы имеют один или два таймера. Обязательным является линейный таймер, генерирующий прерывания центрального процессора через фиксированные интервалы времени. Возможен также программируемый таймер, работающий независимо от линейного, который генерирует однократное прерывание через заданный интервал времени от момента задания. Прерывания такого таймера иногда называются сигналом тревоги (alarm). Если программируемый таймер отсутствует, он может быть смоделирован при помощи интервального таймера и программных средств.
Драйвер линейного таймера осуществляет только обработку его прерываний и в типовом случае может выполнять следующие действия по каждому прерыванию:
- модифицировать системные структуры данных службы времени и даты;
- увеличивать счетчик виртуального времени активного процесса;
- если планирование процессов ведется с квантованием времени,
уменьшать счетчик кванта активного процесса и, если счетчик обратился в ноль, вызывать планировщик;
- если не используется программируемый таймер - уменьшать счетчик тревоги и, если он обратился в ноль, вызывать системную задачу, ожидающую этого сигнала. Линейный таймер может поддерживать целый список таких сигналов тревоги, используемых разными
процессами и системными службами, временные выдержки могут задаваться для обеспечения протоколов обмена, измерения производительности системы и т.п.
Драйвер клавиатуры. Этот драйвер предназначен для ввода символов с клавиатуры терминала. В большинстве аппаратных архитектур нажатие любой клавиши на клавиатуре вызывает прерывание. Обработчик этого прерывания в типовом случае выполняет:
- чтение кода клавиши и перевод его в код символа;
- запоминание кодов символов в своем буфере;
- распознавание специальных клавиш и комбинаций клавиш (например, Ctrl+Break) и вызов специальных их обработчиков;
- обработку специальных клавиш редактирования содержимого буфера (например, BackSpace).
Большинство драйверов позволяют пользователю терминала производить упреждающий ввод данных - до того, как на них поступит запрос из программы. Введенные данные становятся доступными для чтения при нажатии специальной клавиши (например, Enter). Код этой клавиши сохраняется в буфере как признак конца строки. При поступлении запроса на чтение данных с клавиатуры драйвер выбирает из буфера строку - до признака конца строки. Если этот признак
отсутствует, то процесс, выдавший запрос, блокируется до появления законченной строки в буфере драйвера. Некоторые драйверы запоминают введенные строки в стеке и обрабатывают также специальные клавиши, позволяющие выбирать строки из стека.
Драйверы дисковых запоминающих устройств. Обычной функцией такого драйвера является перевод виртуального адреса на диске в реальный (физический). Физический адрес на диске состоит из трех компонент: головка, дорожка, сектор (в дисковых архитектурах без разбиения на сектора - смещение на дорожке). Драйвер же формирует для процессов виртуальный диск, представляемый, как линейная последовательность секторов, виртуальным адресом является номер сектора.
Интересной функцией дискового драйвера может быть планирование запросов на ввод-вывод с целью повышения эффективности обмена. В соответствии со структурой физического адреса доступ к данным на диске состоит из трех этапов - выборок составляющих этого адреса: выбора головки, выбора дорожки и выбора сектора. Выбор головки чтения/записи производится простым электрическом переключением практически мгновенно. Выбор дорожки - самый времяемкий
этап: он требует механического перемещения головок к требуемой дорожки; время этого перемещения зависит от расстояния перемещения. Выбор сектора на дорожке требует ожидания момента, когда требуемый сектор окажется под головкой (за счет вращения диска), время выбора сектора много меньше времени выбора дорожки.
Драйвер упорядочивает очередь запросов таким образом, чтобы минимизировать среднее время поиска дорожки. Обсуждение стратегий
обслуживания мы далее ведем, исходя из предположения о случайном распределении запросов по пространству диска. Обслуживание очереди по дисциплине FCFS, очевидно, приведет к хаотическому перемещению головок и в результате - к невысокой пропускной способности
драйвера и значительным механическим нагрузкам на дисковод.