Смекни!
smekni.com

Операционные системы 5 (стр. 11 из 43)

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

Блок прерываний выполняет примерно тот алгоритм, который в п. 2.5.1 назывался вводом/выводом по прерываниям. Система вызывает этот блок, когда получает сигнал прерывания от устройства, обслуживаемого драйвером. Закончив выполнение заявки, блок прерываний возвращает управление блоку стратегии для завершения операции.

Помимо трех основных блоков, в разных ОС драйверы могут содержать, например, блок инициализации (он используется один раз при загрузке ОС, а затем может быть выгружен из памяти), блок изменения параметров драйвера и др.

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

2.8. Управление устройствами в MS-DOS

2.8.1. Уровни доступа к устройствам

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

Уровни доступа к устройствам показаны на рис. 2‑5.

Рис. 2‑5

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

В работе MS-DOS широко используются возможности, предоставляемые BIOS (BasicInput/OutputSystem, базовая система ввода/вывода) – набором программных модулей, записанных в постоянной памяти (ПЗУ) компьютера. BIOS по умолчанию выполняет обработку всех аппаратных прерываний, если эту работу не берет на себя DOS или прикладная программа. Кроме того, BIOS содержит процедуры обработки ряда программных прерываний ввода/вывода.

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

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

Функции DOS, в отличие от прерываний BIOS, работают не с конкретной аппаратурой, а с именованными устройствами. Имена устройств задаются в заголовках соответствующих драйверов. Например, для DOS клавиатура и экран объединяются драйвером консольного устройства CON.

Процедуры ввода/вывода, используемые в языках программирования (например, Read и Write в Паскале, scanf и printf в C), при компиляции реализуются как подходящие вызовы функций DOS или, в особых случаях, программных прерываний BIOS.

2.8.2. Драйверы устройств в MS-DOS

Драйвер устройства в MS-DOS состоит из трех блоков с известными нам названиями: заголовок драйвера, блок стратегии и блок прерываний. При близком рассмотрении оказывается, однако, что сходство ограничивается в основном названиями блоков.

Заголовок драйвера содержит основную информацию об устройстве: символьное или блочное устройство; для символьных устройств – имя устройства; для блочных – количество однотипных устройств, обслуживаемых данным драйвером; не является ли данное устройство системной консолью, системными часами или пустым устройством; какие специальные операции поддерживает устройство.

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

Если в файле конфигурации CONFIG.SYS указаны имена файлов дополнительных (загружаемых) драйверов, то эти драйверы помещаются в списке впереди стандартных системных драйверов. Поэтому, если имя устройства для загружаемого драйвера совпадает с именем стандартного устройства MS-DOS, то будет вызван загружаемый драйвер, а не стандартный.

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

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

2.8.3. Управление символьными устройствами

Работу MS-DOS с символьными устройствами интереснее всего рассмотреть на примере клавиатуры. Путь, который проходят при этом вводимые данные, схематично показан на рис. 2‑6.

Рис. 2‑6

Когда пользователь нажимает клавишу, клавиатура переходит в состояние готовности и по этому поводу посылает сигнал аппаратного прерывания Int 09h. Одновременно в порт, к которому подключена клавиатура, посылается скан-код нажатия клавиши. Этот код представляет собой однобайтовое число, означающее порядковый номер нажатой клавиши. Если клавиша долго удерживается нажатой, то через некоторое время начинается «автоповтор» – сигнал прерывания и скан-код посылаются многократно. Наконец, когда клавиша отпускается, генерируется еще одно прерывание и посылается скан-код отпускания клавиши, который отличается от кода нажатия единичным значением старшего бита. Этим практически исчерпываются аппаратные события, связанные с клавиатурой. Все остальное делается программно.

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

Подпрограмма BIOS, обрабатывающая аппаратное прерывание от клавиатуры, должна, во-первых, запоминать текущее состояние клавиатуры: нажаты или нет «сдвиговые» клавиши Shift, Ctrl, Alt, включены или нет режимы Caps Lock, Num Lock. Во-вторых, обработчик должен с учетом этого состояния определить, какой символ хотел ввести пользователь. Одна и та же клавиша может, например, означать букву ‘Z’ прописную или строчную, русскую букву ‘Я’ прописную или строчную, а также быть частью комбинаций Ctrl+Z, Alt+Z. Соответствующий символ будет помещаться в буфер клавиатуры в виде двух байт: скан-код нажатой клавиши и ASCII-код символа. Для некоторых клавиш и комбинаций, которым не соответствует никакой ASCII-код (например, F1, Insert, Ctrl+Home, Alt+буква, -), фирма IBM разработала собственный набор «расширенных» кодов.

Буфер клавиатуры может вместить до 15 введенных символов, а при переполнении начинает противно пищать.

Программное прерывание Int 16h также обрабатывается BIOS’ом. Его назначение – удовлетворять запросы программ, обращающихся к клавиатуре. Наиболее часто используются следующие три функции этого прерывания.

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