Драйвер устройства это программа управляющая работой устройства ввода вывода
Одной из главных функций ОС является управление всеми устройствами ввода-вывода компьютера. ОС должна передавать устройствам команды, перехватывать прерывания и обрабатывать ошибки; она также должна обеспечивать интерфейс между устройствами и остальной частью системы. В целях развития интерфейс должен быть одинаковым для всех типов устройств (независимость от устройств).
Физическая организация устройств ввода-вывода
Устройства ввода-вывода делятся на два типа: блок-ориентированные устройства и байт-ориентированные устройства. Блок-ориентированные устройства хранят информацию в блоках фиксированного размера, каждый из которых имеет свой собственный адрес. Самое распространенное блок-ориентированное устройство - диск. Байт-ориентированные устройства не адресуемы и не позволяют производить операцию поиска, они генерируют или потребляют последовательность байтов. Примерами являются терминалы, строчные принтеры, сетевые адаптеры. Однако некоторые внешние устройства не относятся ни к одному классу, например, часы, которые, с одной стороны, не адресуемы, а с другой стороны, не порождают потока байтов. Это устройство только выдает сигнал прерывания в некоторые моменты времени.
Внешнее устройство обычно состоит из механического и электронного компонента. Электронный компонент называется контроллером устройства или адаптером. Механический компонент представляет собственно устройство. Некоторые контроллеры могут управлять несколькими устройствами. Если интерфейс между контроллером и устройством стандартизован, то независимые производители могут выпускать совместимые как контроллеры, так и устройства.
Операционная система обычно имеет дело не с устройством, а с контроллером. Контроллер, как правило, выполняет простые функции, например, преобразует поток бит в блоки, состоящие из байт, и осуществляют контроль и исправление ошибок. Каждый контроллер имеет несколько регистров, которые используются для взаимодействия с центральным процессором. В некоторых компьютерах эти регистры являются частью физического адресного пространства. В таких компьютерах нет специальных операций ввода-вывода. В других компьютерах адреса регистров ввода-вывода, называемых часто портами, образуют собственное адресное пространство за счет введения специальных операций ввода-вывода (например, команд IN и OUT в процессорах i86).
ОС выполняет ввод-вывод, записывая команды в регистры контроллера. Например, контроллер гибкого диска IBM PC принимает 15 команд, таких как READ, WRITE, SEEK, FORMAT и т.д. Когда команда принята, процессор оставляет контроллер и занимается другой работой. При завершении команды контроллер организует прерывание для того, чтобы передать управление процессором операционной системе, которая должна проверить результаты операции. Процессор получает результаты и статус устройства, читая информацию из регистров контроллера.
Организация программного обеспечения ввода-вывода
Основная идея организации программного обеспечения ввода-вывода состоит в разбиении его на несколько уровней, причем нижние уровни обеспечивают экранирование особенностей аппаратуры от верхних, а те, в свою очередь, обеспечивают удобный интерфейс для пользователей.
Ключевым принципом является независимость от устройств. Вид программы не должен зависеть от того, читает ли она данные с гибкого диска или с жесткого диска.
Очень близкой к идее независимости от устройств является идея единообразного именования, то есть для именования устройств должны быть приняты единые правила.
Еще один ключевой вопрос - это использование блокирующих (синхронных) и неблокирующих (асинхронных) передач. Большинство операций физического ввода-вывода выполняется асинхронно - процессор начинает передачу и переходит на другую работу, пока не наступает прерывание. Пользовательские программы намного легче писать, если операции ввода-вывода блокирующие - после команды READ программа автоматически приостанавливается до тех пор, пока данные не попадут в буфер программы. ОС выполняет операции ввода-вывода асинхронно, но представляет их для пользовательских программ в синхронной форме.
Последняя проблема состоит в том, что одни устройства являются разделяемыми, а другие - выделенными. Диски - это разделяемые устройства, так как одновременный доступ нескольких пользователей к диску не представляет собой проблему. Принтеры - это выделенные устройства, потому что нельзя смешивать строчки, печатаемые различными пользователями. Наличие выделенных устройств создает для операционной системы некоторые проблемы.
- Обработка прерываний,
- Драйверы устройств,
- Независимый от устройств слой операционной системы,
- Пользовательский слой программного обеспечения.
Рис. 2.30. Многоуровневая организация подсистемы ввода-вывода
Обработка прерываний
Драйверы устройств
Весь зависимый от устройства код помещается в драйвер устройства. Каждый драйвер управляет устройствами одного типа или, может быть, одного класса.
В операционной системе только драйвер устройства знает о конкретных особенностях какого-либо устройства. Например, только драйвер диска имеет дело с дорожками, секторами, цилиндрами, временем установления головки и другими факторами, обеспечивающими правильную работу диска.
Драйвер устройства принимает запрос от устройств программного слоя и решает, как его выполнить. Типичным запросом является чтение n блоков данных. Если драйвер был свободен во время поступления запроса, то он начинает выполнять запрос немедленно. Если же он был занят обслуживанием другого запроса, то вновь поступивший запрос присоединяется к очереди уже имеющихся запросов, и он будет выполнен, когда наступит его очередь.
Первый шаг в реализации запроса ввода-вывода, например, для диска, состоит в преобразовании его из абстрактной формы в конкретную. Для дискового драйвера это означает преобразование номеров блоков в номера цилиндров, головок, секторов, проверку, работает ли мотор, находится ли головка над нужным цилиндром. Короче говоря, он должен решить, какие операции контроллера нужно выполнить и в какой последовательности.
После передачи команды контроллеру драйвер должен решить, блокировать ли себя до окончания заданной операции или нет. Если операция занимает значительное время, как при печати некоторого блока данных, то драйвер блокируется до тех пор, пока операция не завершится, и обработчик прерывания не разблокирует его. Если команда ввода-вывода выполняется быстро (например, прокрутка экрана), то драйвер ожидает ее завершения без блокирования.
Независимый от устройств слой операционной системы
Большая часть программного обеспечения ввода-вывода является независимой от устройств. Точная граница между драйверами и независимыми от устройств программами определяется системой, так как некоторые функции, которые могли бы быть реализованы независимым способом, в действительности выполнены в виде драйверов для повышения эффективности или по другим причинам.
- обеспечение общего интерфейса к драйверам устройств,
- именование устройств,
- защита устройств,
- обеспечение независимого размера блока,
- буферизация,
- распределение памяти на блок-ориентированных устройствах,
- распределение и освобождение выделенных устройств,
- уведомление об ошибках.
Остановимся на некоторых функциях данного перечня. Верхним слоям программного обеспечения не удобно работать с блоками разной величины, поэтому данный слой обеспечивает единый размер блока, например, за счет объединения нескольких различных блоков в единый логический блок. В связи с этим верхние уровни имеют дело с абстрактными устройствами, которые используют единый размер логического блока независимо от размера физического сектора.
При создании файла или заполнении его новыми данными необходимо выделить ему новые блоки. Для этого ОС должна вести список или битовую карту свободных блоков диска. На основании информации о наличии свободного места на диске может быть разработан алгоритм поиска свободного блока, независимый от устройства и реализуемый программным слоем, находящимся выше слоя драйверов.
Пользовательский слой программного обеспечения
Хотя большая часть программного обеспечения ввода-вывода находится внутри ОС, некоторая его часть содержится в библиотеках, связываемых с пользовательскими программами. Системные вызовы, включающие вызовы ввода-вывода, обычно делаются библиотечными процедурами. Если программа, написанная на языке С, содержит вызов
то библиотечная процедура write будет связана с программой. Набор подобных процедур является частью системы ввода-вывода. В частности, форматирование ввода или вывода выполняется библиотечными процедурами. Примером может служить функция printf языка С, которая принимает строку формата и, возможно, некоторые переменные в качестве входной информации, затем строит строку символов ASCII и делает вызов write для вывода этой строки. Стандартная библиотека ввода-вывода содержит большое число процедур, которые выполняют ввод-вывод и работают как часть пользовательской программы.
Другой категорией программного обеспечения ввода-вывода является подсистема спулинга (spooling). Спулинг - это способ работы с выделенными устройствами в мультипрограммной системе. Рассмотрим типичное устройство, требующее спулинга - строчный принтер. Хотя технически легко позволить каждому пользовательскому процессу открыть специальный файл, связанный с принтером, такой способ опасен из-за того, что пользовательский процесс может монополизировать принтер на произвольное время. Вместо этого создается специальный процесс - монитор, который получает исключительные права на использование этого устройства. Также создается специальный каталог, называемый каталогом спулинга. Для того, чтобы напечатать файл, пользовательский процесс помещает выводимую информацию в этот файл и помещает его в каталог спулинга. Процесс-монитор по очереди распечатывает все файлы, содержащиеся в каталоге спулинга.
1. Устройство ввода информации с листа бумаги называется:
- a. Плоттер
- b. Стример
- c. Драйвер
- d. Сканер
Ответ: d
2. В какой системе счисления работает компьютер?
- a. В двоичной
- b. в шестнадцатеричной
- c. в десятичной
- d. все ответы правильные
Ответ: a
3. Драйвер - это:
- a. устройство длительного хранения информации
- b. программа, управляющая конкретным внешним устройством
- c. устройство ввода
- d. устройство вывода
Ответ: b
4. Программа - это:
- a. алгоритм, записанный на языке программирования
- b. набор команд операционной системы компьютера
- c. ориентированный граф, указывающий порядок исполнения команд компьютера
- d. протокол взаимодействия компонентов компьютерной сети
Ответ: a
5. При подключении компьютера к телефонной сети используется:
- a. модем
- b. факс
- c. сканер
- d. принтер
Ответ: a
6. Укажите устройство и для ввода, и для вывода информации.
- a. дигитайзер
- b. Принтер
- c. Жесткий диск
- d. Сканер
Ответ: d
7. Какое устройство ПК предназначено для вывода информации?
- a. Процессор
- b. Монитор
- c. Клавиатура
- d. Сканер
Ответ: b
8. К внешней памяти относятся:
- a. модем, жесткий диск,
- b. сканер, жесткий диск,
- c. жесткий диск, флеш-память,
- d. ОЗУ, флеш-память.
Ответ: c
9. В состав процессора входят:
- a. устройства записи информации, чтения информации
- b. арифметико-логическое устройство, устройство управления
- c. устройства ввода и вывода информации
- d. устройство для чтения информации
Ответ: b
10. Перед отключением компьютера информацию можно сохранить
- a. в оперативной памяти
- b. во внешней памяти
- c. в контроллере магнитного диска
Ответ: b
11. Тип принтеров, при котором изображение создается путем механического давления на бумагу через ленту с красителем -
- a. ударного типа (матричные)
- b. струйные
- c. лазерные
- d. термические
Ответ: a
12. Мониторов не бывает
- a. монохромных
- b. жидкокристаллических
- c. на основе ЭЛТ
- d. инфракрасных
Ответ: d
13. При отключении компьютера вся информация стирается
- a. на CD-ROM диске
- b. в оперативной памяти
- c. на гибком диске
- d. на жестком диске
Ответ: b
14. Дано: а = ЕE16.
Какое из чисел c, записанных снизу в двоичной системе счисления, удовлетворяет неравенству: c>a.
Ответ: c
15. Считая, что каждый символ кодируется одним байтом, определите, чему равен информационный объем в слове: Квадрат
- a. 54 бит
- b. 56 бит
- c. 88 бит
- d. 7 бит
Ответ: b
16. Считая, что каждый символ кодируется 16-ю битами, оцените информационный объем следующей пушкинской фразы в кодировке Unicode, имея в виду 1 пробел между словами:
Привычка свыше нам дана:
Замена счастию она.
- a. 44 бита
- b. 704 бита
- c. 44 байта
- d. 704 байта
Ответ: b
17. Три с половиной терабайта содержат . гигабайт информации
Ответ: b
18. Значение выражения 116 + 108 * 102 в двоичной системе счисления равно:
Ответ: b
19. Для какого символьного выражения верно высказывание:
Первая буква гласная → Третья буква согласная?
- a. abedc
- b. becde
- c. babas
- d. abcab
Ответ: d
20. Дан блок программы:
C = 5
For i = 3 To 5
C = C + 1
Next i
X = C + 5
Значение X в результате работы этого блока?
Ответ: c
21. Строки в рабочей книге MS Excel обозначаются:
- a. римскими цифрами
- b. русскими буквами
- c. латинскими буквами
- d. арабскими цифрами
Ответ: d
22. В ответе укажите номера тех функций, которые относятся к категории статистические:
- a. МИН
- b. МАКС
- c. СУММ
- d. СРЗНАЧ
- e. ЕСЛИ
Ответ: a b d
23. Как обозначается команда присваивания в PascalABC?
Выберите один из вариантов ответа:
Ответ: c
24. Определите значение переменной b после выполнения следующего фрагмента программы, где a и b – вещественные (действительные) переменные:
a := -5;
b := 5 + 7 * a;
b := b / 2 * a;
Ответ: c
25. Для каждой модели из первой колонки определите, к какому типу она относится.
Модель | Тип модели |
1) Закон Ньютона | a) Физическая (натурная) |
2) Игрушечный автомобиль | b) Воображаемая |
3) Объёмная модель куба | c) Информационная |
4) Чертёж развёртки куба | |
5) Программа на языке программирования | |
6) Радиоуправляемая модель самолёта | |
7) Бесконечность |
Ответ: 1c, 2a, 3a, 4c, 5c, 6a, 7b
Всем удачи!
Возможно вам так же будет интересно:
Если я Вам помог - оставьте свой отзыв или поделитесь сайтом с друзьями в социальных сетях!
Эта телефонная система LG Electronics Voice over IP (VoIP) основывается на Windows Embedded CE. Фотография с разрешения Mike Hall.
Введение в драйверы устройств В/В
Драйверы устройств помогают создать слой абстракции между оборудованием и прикладными программами пользователя. Типичный пользователь , разрабатывающий приложение , не должен понимать низко-уровневые детали оборудования каждого интерфейса. Вместо этого прикладная программа вызывает API ОС, который вызывает драйвер устройства. Работая на более высоком уровне абстракции, используя ОС и драйверы устройств, программисты приложений могут быть более продуктивными. При использовании ОС и драйверов устройств приложения можно переносить на различные аппаратные платформы с меньшими усилиями, и система будет также более стабильной и безопасной. ОС является критически важной в планировании, размещении, и управлении устройствами, которые совместно используются несколькими процессами. В качестве примера представьте, что произойдет, если два приложения начнут одновременно посылать символьные данные непосредственно оборудованию принтера. В результате получится случайная смесь символов на каждой напечатанной странице.
Большинство распространенных драйверов устройств поставляются вместе с ОС или доступны производителям микросхем, но многие нужно будет переносить на новую аппаратную платформу, так как даже небольшие изменения, такие как задание адреса порта В/В или уровня прерывания могут требовать небольших модификаций кода драйвера.
Одной из проблем, постоянно встречающейся разработчикам встроенных систем, является необходимость разработки драйверов устройств для уникального оборудования, вводимого при проектировании каждой новой платы. Документация по интерфейсам драйверов и примеры драйверов устройств поставляются с каждой ОС. Детали реализации драйверов варьируются от ОС к ОС. Может также поставляться инструмент типа мастера, помогающий сгенерировать шаблонный код, необходимый в новом драйвере устройства для правильного взаимодействия с ОС. В некоторых случаях драйверы устройств покупаются даже у сторонних разработчиков или разрабатываются внешними консультантами. Написаны целые книги по теме написания драйверов устройств. Библиотеки драйверов устройств CE перечислены в таблице 9.1.
Модель потокового интерфейса для драйверов устройств
Драйвером 1 Part of the material presented in this Chapter was obtained from or is derived from the CE 6.0 on-line help files, MEDC 2006 conference presentations by members of the Windows Embedded CE design team , and Microsoft’s Windows Embedded CE Professional Training Materials. Reprinted with Permission of Microsoft Corporation. с потоковым интерфейсом является любой драйвер, который предоставляет функции потокового интерфейса, независимо от типа устройства, которым управляет драйвер. Модель потокового интерфейса является простейшим способом реализации большинства драйверов пользователя, и приложения обращаются к ним с помощью обычных функций API файловой системы. Подобно многим свойствам ОС, подход на основе потокового интерфейса ведет свое начало из первых версий Unix.
Потоковый интерфейс подходит для любого устройства В/В, которое можно логически считать источником или стоком данных. То есть, любое периферийное устройство, которое создает или потребляет потоки данных как свою основную функцию, является хорошим кандидатом для предоставления потокового интерфейса. Примером является устройство потокового порта. Примером устройства, которое не создает и не потребляет данные в традиционном смысле, будет устройство дисплея, и действительно, для управления оборудованием дисплея потоковый интерфейс не предоставляется.
Потоковый интерфейс может использовать другой нижележащий драйвер устройства для доступа к физическим периферийным устройствам, которыми управляет драйвер, или он может обращаться к устройству непосредственно, если устройство отражено в память. Драйверы аудио-устройств для встроенного аудио-оборудования являются примером прямого доступа.
Сами функции потокового интерфейса создаются таким образом, чтобы как можно ближе соответствовать семантике обычных интерфейсов прикладного программирования (API) файловых систем, таких как CreateFile , WriteFile , ReadFile , IOControl , и CloseHandle . В качестве побочного эффекта такого дизайна устройства, которые управляются потоковым интерфейсом, доступны для приложений через файловую систему; приложения взаимодействуют с драйвером, открывая специальные файлы в файловой системе.
Драйверы потокового интерфейса могут иметь монолитную архитектуру или архитектуру с двумя слоями, MDD и PDD , как показано на рисунке 9.1.
Рис. 9.1. Две альтернативные архитектуры драйвера потокового интерфейса. Монолитный драйвер потокового интерфейса или Разделенный на слои драйвер потокового интерфейса. В разделенной на слои архитектуре драйвера в CE два слоя называются MDD и PDD
Интерпретация устройств как специальных файлов распространена во многих операционных системах, включая настольные версии Microsoft Windows и даже первые версия Unix. Там устройства печати традиционно представлялись именами специальных файлов LPTx:, а последовательные порты именами специальных файлов COMx:, и т.д.
Несмотря на базовые характеристики потокового интерфейса, его можно реализовать различным образом. Например, даже хотя потоковый интерфейс обычно создается для периферийных устройств независимыми поставщиками оборудования ( IHV ), производители оригинального оборудования (OEM) могут предоставлять потоковый интерфейс для определенных встроенных устройств.
В некоторых менее распространенных случаях драйверы потокового интерфейса могут переупаковывать существующие ресурсы, обычно таким образом, который специфические приложения смогут более легко использовать. Например, такой тип драйвера потокового интерфейса может управлять приемником системы глобального позиционирования (GPS) с последовательным интерфейсом. В этом примере ISV может выбрать создание специального драйвера потокового интерфейса для работы в соединении с приложением отображения GPS. Многие приемники GPS соединяются с последовательными портами. Приложение отображения GPS может, поэтому, открыть специальный файл COMx:, соответствующий последовательному порту и непосредственно взаимодействовать с приемником GPS.
Однако приемник GPS может предоставлять данные позиционирования в неудобном формате, или создатель приложения может захотеть сохранить скрытыми детали управления специальными моделями приемников GPS. Поэтому можно написать драйвер потокового интерфейса для обеспечения взаимодействия между приложением и приемником GPS. Драйвер будет взаимодействовать с приемником GPS как и раньше через специальный файл COMx:, но может переупаковывать данные позиционирования в более удобном формате для приложения. Драйвер может предоставлять свои собственные службы как специальный файл GPSx:, который будет открывать приложение, чтобы прочитать данные позиционирования.
Драйвер потокового интерфейса получает команды от Device Manager или из приложений посредством вызовов файловой системы. Драйвер инкапсулирует всю информацию, которая необходима для трансляции этих команд в соответствующие действия на устройствах, которыми он управляет.
Все драйверы потоковых интерфейсов, управляют ли они встроенными устройствами или устанавливаемыми устройствами, загружаются ли они во время начальной загрузки или загружаются динамически, имеют похожие взаимодействия с другими системными компонентами. Рисунок 9.2 показывает архитектуру драйверов потокового интерфейса для встроенных устройств, которые загружаются Device Manager во время начальной загрузки.
Различные вопросы могут влиять на конструктивные решения во время реализации динамически подключаемой библиотеки (DLL) драйвера потокового интерфейса. Чтобы реализовать драйвер потокового интерфейса, создайте DLL, содержащую требуемые точки входа для драйверов, и затем решите, хотите ли вы реализовать одиночный или множественный доступ к драйверу.
Можно реализовать драйвер только с точками входа Init и Deinit и без префикса устройства. Невозможно получить доступ к этому драйверу с помощью CreateFile. PCIBUS и RegEnum являются двумя примерами такого типа драйвера. Эти драйверы находятся в каталогах ..\WINCE600\Public\Common\OAK\Drivers\PCIbus и ..\WINCE600\Public\Common\ OAK\Drivers\RegEnum .
Если DEVFLAGS_NAKEDENTRIES определен в подключе реестра Flags драйвера, то имена точек входа могут быть лишены отличий; например, Open, Close, и т. д. Пример драйвера батареи, который находится в ..\WINCE600\Public\Common\OAK\Drivers\Battdrvr , является примером драйвера, который использует точки входа без отличий. Настройки реестра драйвера батареи должны тем не менее включать префикс.
Реализации этих точек входа должны объявляться для экспорта из DLL, размещая __declspec(dllexport) перед объявлением функции. При разработке в C++, точки входа должны также объявляться как внешние "C".
Таблица 9.2 показывает функции драйвера потокового интерфейса с описанием назначения каждой из них. XXX в имени каждой функции заменяется трехсимвольным именем устройства. Эти функции определяются внутренне только для менеджера устройств, а не для приложений пользователя.
Так как периферийные устройства доступны приложениям как файлы, когда создается потоковый интерфейс, то нужно предоставить реализацию такого файла. Поэтому, рассмотрите, будет ли это практично, на основе возможностей устройства, которые предоставляет драйвер, чтобы позволить нескольким приложениям иметь одновременный доступ к файлу, который представляет устройство. То есть, рассмотрите, может ли драйвер иметь несколько открытых указателей файлов на своем устройстве. Драйвер потокового интерфейса может реализовать одиночный доступ или множественный доступ, используя параметр hOpenContext, передаваемый всем функциям В/В файла.
Чтобы реализовать множественный доступ, каждый вызов функции XXX_Open должен возвращать различное значение для hOpenContext . Драйвер устройства должен отслеживать, какие возвращаемые значения из XXX_Open используются. Последующие обращения к XXX_Close , XXX_Read , XXX_Write , XXX_Seek , и XXX_IOControl передают эти значения назад драйверу устройства, позволяя драйверу идентифицировать, какими внутренними структурами данных манипулировать.
Для реализации одиночного доступа, только первый вызов XXX_Open должен возвращать действительное значение hOpenContext . Пока это значение остается действительным, что будет иметь место, пока для этого значения не будет вызвана функция XXX_Close , последующие обращения к XXX_Open должны возвращать NULL вызывающему приложению, чтобы указать на отказ.
Драйвер – компьютерное программное обеспечение, используемое для управления каждым подключенным к компьютеру устройством ввода-вывода, учитывая его особенности. Оно создается производителем устройства и поставляется вместе с этим устройством. Поскольку для каждой операционной системы нужны собственные драйверы, производитель устройства обычно поставляет драйверы для нескольких наиболее популярных операционных систем.
В большинстве случаев драйвер устройства управляет одним типом устройства или как максимум одним классом родственных устройств. Тем не менее технически вполне возможно создание одного драйвера устройства, управляющего несколькими разнородными устройствами. Однако, в большинстве случаев это является не самой лучшей идеей.
Содержание
Драйвер и операционная система
Чтобы получить доступ к аппаратной части устройства, то есть к регистрам контроллера, драйвер устройства, как правило, должен быть частью ядра операционной системы, по крайней мере в существующих на сегодняшний день архитектурах. Но вообще-то можно создавать и драйверы, работающие в пространстве пользователя, используя при этом системные вызовы для чтения и записи регистров устройств. Такое решение позволит изолировать ядро от драйверов и драйверы друг от друга, устранив при этом основной источник системных сбоев — «сырые» драйверы, тем или иным образом мешающие работе ядра. Несомненно, это хороший выход из положения при создании высоконадежных систем.
Так как разработчики любых операционных систем знают, что драйверы, созданные другими разработчиками, будут устанавливаться в их систему, им нужна такая архитектура, которая позволит подобную установку. А это значит, что должна быть вполне определенная модель того, чем занимается драйвер и как он взаимодействует со всей операционной системой. Как показано на рис. 1, драйверы устройств обычно размещаются ниже остальных компонентов операционной системы.
Обычно операционная система относит драйверы к одной из немногочисленных категорий. Самые распространенные категории — это драйверы блочных устройств, к ним относятся драйверы дисков, содержащих множество блоков данных, к которым можно обращаться независимо от всех остальных блоков, и драйверы символьных устройств, к которым относятся драйверы клавиатур и принтеров — устройств, которые генерируют или воспринимают поток символов.
В некоторых системах операционная система представляет собой единую программу в двоичных кодах, в которой содержатся все необходимые ей скомпилированные драйверы. Такая схема долгие годы была нормой для систем семейства UNIX, поскольку они работали в компьютерных центрах, где устройства ввода-вывода менялись очень редко. При добавлении нового устройства системный администратор просто перекомпилировал ядро с новым драйвером для создания нового двоичного кода.
С наступлением эры персональных компьютеров с несметным количеством устройств ввода-вывода эта модель уже не работает. Лишь немногие пользователи способны перекомпилировать или перекомпоновать ядро, даже если у них будут исходные коды или объектные модули, что случается довольно редко. Вместо этого операционные системы, начиная с MS-DOS, перешли к модели, в которой драйверы стали динамически загружаться в систему в процессе работы. Управление загрузкой драйверов ведется в разных системах по-разному.
Алгоритм работы
Затем драйвер может проверить, используется ли устройство в данный момент. Если оно используется, запрос будет поставлен в очередь для последующей обработки. Если устройство простаивает, проверяется состояние аппаратуры, чтобы определить, может ли запрос быть обработан. Перед началом передачи данных может понадобиться включить устройство или запустить его двигатель. Как только устройство включится и будет готово к работе, им можно будет управлять.
Управление устройством означает выдачу в его адрес последовательности команд. Именно драйвер определяет последовательность команд в зависимости от того, что должно быть сделано. После того как драйвер поймет, какие команды он собирается выдать, он начнет записывать их в регистры контроллера устройства. После записи каждой команды в контроллер может потребоваться проверка того, принял ли контроллер команду и готов ли к приему следующей команды. Эта последовательность повторяется до тех пор, пока не будут выданы все команды. Некоторым контроллерам можно указывать на связанный список команд (в памяти) и предписывать самостоятельное чтение и обработку этих команд без дальнейшей помощи со стороны операционной системы.
После того как команды были выданы, может сложиться одна из двух ситуаций. В большинстве случаев драйвер должен ждать, пока контроллер не сделает в его интересах какую-нибудь работу, поэтому он самоблокируется до тех пор, пока не поступит прерывание на его разблокировку. Но в других случаях операция завершается без задержки и драйверу не нужно блокироваться. В качестве примера последней ситуации можно привести прокрутку экрана в символьном режиме, требующую лишь записи нескольких байтов в регистры контроллера. Для этого не нужно никаких механических перемещений, поэтому вся операция может быть завершена за несколько наносекунд.
В первом случае заблокированный драйвер будет активизирован прерыванием. Во втором случае он никогда не будет переходить в неактивное состояние. В любом случае по завершении операции драйвер должен провести проверку на отсутствие ошибок. Если все в порядке, драйвер может получить данные для передачи программному обеспечению, не зависящему от применяемого устройства. И наконец, он возвращает вызывавшей его программе определенную информацию о состоянии устройства, наличии или отсутствии ошибок. Если в очереди были какие-нибудь другие запросы, то теперь один из них может быть выбран и запущен на выполнение. Если запросов в очереди не было, драйвер блокируется в ожидании следующего запроса.
Функции программного обеспечения, не зависящего от конкретных устройств
Основная роль программного обеспечения, не зависящего от конкретного устройства, состоит в выполнении общих для всех устройств функций ввода-вывода и предоставлении унифицированного интерфейса для программного обеспечения на уровне пользователя. Далее перечисленные задачи будут рассмотрены более подробно.
Предоставление унифицированного интерфейса для драйверов устройств
Одной из острых проблем при создании операционных систем является придание всем устройствам и драйверам ввода-вывода более или менее однообразного вида.
Один из аспектов этой проблемы — интерфейс между драйверами устройств и остальной операционной системой. На рис. 2 (а) показана ситуация, в которой у каждого драйвера устройства имеется собственный интерфейс с операционной системой. Это означает, что функции драйвера, доступные для вызова системой, различаются от драйвера к драйверу. Это может означать, что и функции ядра, в которых нуждается драйвер, различаются от драйвера к драйверу. Все вместе взятое это означает, что обеспечение интерфейса с каждым новым драйвером требует множества новых усилий по созданию программного кода.
В противоположность этому на рис. 2 (б) показана другая конструкция, в которой у всех драйверов имеется одинаковый интерфейс. Теперь стало намного проще подключить новый драйвер, обеспечив его соответствие интерфейсу драйверов. Также это означает, что создатели драйверов знают, чего от них ожидают. Фактически не все устройства абсолютно одинаковы, но обычно приходится иметь дело лишь с небольшим количеством типов устройств, и даже они в целом практически одинаковы.
Все это работает следующим образом. Для каждого класса устройств, таких как диски или принтеры, операционной системой определяется набор функций, которые драйвер должен поддерживать. Для диска в этот набор будут входить не только чтение и запись, но и включение и выключение электропитания, форматирование и другие присущие диску операции. Зачастую драйвер содержит таблицу с указателями на эти функции. При загрузке драйвера операционная система записывает адрес таблицы указателей на функции, чтобы, когда потребуется вызвать одну из этих функций, она могла выполнить опосредованный вызов через таблицу. Таблица указателей на функции определяет интерфейс между драйвером и всей остальной операционной системой. Все устройства определенного класса должны соответствовать этому условию.
Буферизация
Буферизация по многим причинам также является актуальным вопросом как для блочных, так и для символьных устройств. Чтобы понять, в чем состоит одна из таких причин, рассмотрим процесс, которому необходимо прочитать данные, получаемые от ADSL-модема, который многие используют дома для связи с Интернетом. По одной из возможных стратегий работы с поступающими символами нужно заставить пользовательский процесс осуществить системный вызов READ и заблокироваться в ожидании одного символа. При этом прерывание возникает по случаю поступления каждого символа. Процедура обработки прерывания передает символ пользовательскому процессу и снимает с него блокировку. Поместив куда-нибудь символ, процесс переходит к чтению следующего символа и снова блокируется.
Проблема реализации такого способа заключается в том, что пользовательский процесс должен возобновляться для каждого поступающего символа. Из-за низкой эффективности многократных краткосрочных запусков процесса это далеко не самая лучшая модель.
В улучшенном варианте пользовательский процесс предоставляет буфер объемом N символов и выполняет чтение такого же количества символов. Процедура обработки прерывания помещает поступающие символы в этот буфер до тех пор, пока он не заполнится. Затем она возобновляет работу пользовательского процесса. Эта схема работает намного эффективнее предыдущей, но у нее есть один недостаток. Что получится, если буфер выйдет за границу страницы при поступлении очередного символа? Буфер будет зафиксирован в памяти, но если множество процессов начнет фиксировать страницы в памяти, то запас доступных страниц сократится и производительность резко снизится.
Другой широко распространенной формой буферизации является использование кольцевого буфера. Он состоит из области памяти и двух указателей, один из которых указывает на следующее свободное слово, в которое можно поместить новые данные, а другой — на первое слово тех данных в буфере, которые еще не были из него выведены. Во многих случаях аппаратура по мере добавления данных (например, только что поступивших из сети) передвигает вперед первый указатель; операционная система, по мере того как она выводит из буфера и обрабатывает данные, перемещает вперед второй указатель. Оба указателя ходят по кругу, переходя обратно к нижним адресам буфера, как только достигнут его верхних адресов.
Буферизация является широко используемой технологией, но у нее имеются и недостатки. Если данные будут подвергаться буферизации слишком часто, упадет производительность. Рассмотрим, к примеру, сеть, показанную на рис. 4. Здесь пользовательский процесс осуществляет системный вызов для записи данных по сети. Ядро копирует пакет данных в буфер ядра, позволяя пользовательскому процессу немедленно возобновить работу (шаг 1). Теперь пользовательская программа может использовать буфер повторно.
Когда вызывается драйвер, он копирует пакет в контроллер для его последующего вывода (шаг 2). Причина, по которой он не осуществляет вывод в сеть непосредственно из памяти ядра, состоит в том, что как только будет запущена передача пакета, она должна продолжаться на постоянной скорости. Драйвер не может гарантировать, что он будет получать доступ к памяти на постоянной скорости, поскольку множество циклов обращения к шине могут отвлекать на себя каналы DMA и другие устройства ввода-вывода. Неудача при своевременном получении слова приведет к порче пакета. Эту проблему можно устранить за счет буферизации пакета внутри контроллера.
После того как пакет будет скопирован во внутренний буфер контроллера, он копируется в сеть (шаг 3). Биты поступают получателю вскоре после их отправки, поэтому сразу же после отправки последнего бита этот бит поступает получателю, у которого пакет попадает в буфер контроллера. Затем пакет копируется в буфер ядра получателя (шаг 4). И наконец он копируется в буфер процесса получателя (шаг 5). Обычно после этого получатель посылает подтверждение. Когда отправитель получает подтверждение, он имеет возможность послать следующий пакет. Но при этом следует понимать, что операции копирования существенно снижают скорость передачи данных, поскольку шаги должны осуществляться последовательно.
При вводе-выводе данных ошибки являются более распространенным событием, чем в других сферах работы компьютерных устройств. При возникновении ошибок операционная система должна их обработать наилучшим образом. Многие ошибки зависят от специфики конкретного устройства и должны обрабатываться соответствующим драйвером, но структура обработки ошибок не зависит от специфики устройств.
К одному из классов ошибок ввода-вывода относятся ошибки программирования. Они возникают в том случае, если процесс запрашивает что-нибудь невозможное, к примеру запись в устройство ввода информации или чтение из устройства вывода информации. Другие ошибки возникают при предоставлении неверного адреса буфера или указании неверного устройства. На такие ошибки следует весьма простая реакция: вызывающей программе отправляется код возникшей ошибки.
Действия этого программного обеспечения зависят от среды окружения и характера ошибки. Если речь идет о простой ошибке чтения и есть возможность общения с пользователем, то может быть выведено диалоговое окно с вопросом к пользователю, что делать дальше. Варианты могут включать повторение попытки определенное количество раз, игнорирование ошибки или уничтожение вызывающего процесса. Если пользователь недоступен, то, возможно, единственным вариантом будет аварийное завершение системного вызова с указанием кода ошибки.
Распределение и высвобождение выделенных устройств
Некоторые устройства, в любой момент времени могут использоваться только одним процессом. Операционная система должна проверять запросы на использование и принимать их или отвергать в зависимости от доступности запрашиваемого устройства. Простой способ обработки этих запросов заключается в требовании к процессам непосредственно открывать специальные файлы для этих устройств с помощью системных вызовов OPEN. Если устройство недоступно, то системный вызов OPEN потерпит неудачу. Освобождение выделенного устройства происходит после его закрытия с помощью системного вызова CLOSE. Альтернативный подход заключается в использовании специальных механизмов для запроса и освобождения выделенных устройств. Попытка получить в свое распоряжение недоступное устройство приводит не к отказу, а к блокировке процесса, предпринявшего эту попытку. Заблокированные процессы помещаются в очередь. Рано или поздно запрашиваемое устройство станет доступным, и первому процессу из этой очереди будет позволено получить устройство и продолжить свою работу.
Предоставление размера блока, не зависящего от конкретных устройств
У разных дисков могут быть разные размеры секторов. Не зависимое от устройств программное обеспечение должно скрыть этот факт и предоставить расположенным выше уровням унифицированный размер блока, например, рассматривая несколько секторов в качестве одного логического блока. Таким образом, вышестоящие уровни будут работать только с абстрактными устройствами, использующими один и тот же размер логического блока, не зависящий от физического размера сектора. Аналогичным образом некоторые символьные устройства осуществляют побайтовую доставку данных, а другие устройства доставляют данные блоками более крупного размера. Эти различия также могут быть скрыты.
Горячее подключение устройств
Виртуальные драйверы
Драйверы виртуальных устройств представляют собой особый вариант драйверов. Они используются для эмуляции аппаратного устройства, особенно в средах виртуализации, например, когда программа DOS запускается на компьютере Microsoft Windows. Вместо того, чтобы разрешать гостевой операционной системе взаимодействовать с настоящим оборудованием, драйверы виртуальных устройств принимают противоположную роль и эмулируют часть оборудования, так что гостевая операционная система и ее драйверы, запущенные внутри виртуальной машины, имеют только иллюзию доступа к нему. Попытки гостевой операционной системы получить доступ к оборудованию маршрутизируются к драйверу виртуального устройства в операционной системе хоста. Драйвер виртуального устройства также может посылать в виртуальную машину смоделированные события уровня процессора, такие как прерывания.
Читайте также: