Операционная система MS DOS

       

Связь драйвера с операционной системой


Рассмотрим теперь более подробно механизм взаимодействия драйвера и операционной системы.

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

next DD 0FFFFFFFFh attrib DW 8000h strateg DW strateg_proc interrupt DW interrupt_proc dev_name DB 'TESTDRV '

Это символьный драйвер (старший бит поля attrib равен 1), исходный текст содержит только один драйвер (поле next содержит значение 0FFFFFFFFh), имя устройства, которое нужно будет использовать при обращении к драйверу - TESTDRV. Имя устройства не должно совпадать с именем файла, содержащего символьный драйвер, иначе Вы не сможете обратиться к файлу, например, для его переименования - DOS будет работать не с файлом, а с устройством.

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

req_off DW ? req_seg DW ?

Тогда программа стратегии должна записать содержимое регистра ES в поле req_seg, а регистра BX - в поле req_off:

strateg_proc: mov cs:req_off,bx mov cs:req_seg,es ret

Драйвер состоит из одного сегмента кодов, поэтому для адресации данных используется сегментный регистр CS.

Запрос операционной системы к драйверу соcтоит из заголовка, имеющего фиксированный формат и длину 13 байт, и переменной части, размер и формат которой зависит от выполняемой функции.

Приведем формат заголовка запроса:



(0) 1 size Длина запроса в байтах (длина заголовка запроса плюс длина переменной части запроса)
(+1) 1 unit Номер устройства (используется для блочных устройств, указывает, с каким именно устройством, обслуживаемым драйвером, будет работать операционная система)
(+2) 1 cmd Код команды, которую требуется выполнить (может иметь значение от 0 до 18h)
(+3) 2 status Слово состояния устройства, заполняется драйвером перед возвратом управления операционной системе
(+5) 8 reserved Зарезервировано
<
После вызова программы стратегии DOS передает управление программе прерывания (без параметров). Задача программы прерывания - выполнить команду, код которой находится в поле cmd заголовка запроса. Если драйвер блочного устройства обслуживает несколько логических устройств, то в поле unit находится номер устройства, для которого необходимо выполнить команду.

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

Как результаты выполнения команды возвращаются DOS?

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

Приведем формат слова состояния устройства:

Бит Назначение
0-7 Код ошибки устройства (если команда выполнена с ошибкой и драйвер установил признак ошибки (бит 15) в единицу, в это поле он должен записать код ошибки).
8 Команда выполнена. Этот бит всегда устанавливается драйвером перед тем, как он возвращает управление операционной системе.
9 Занято. Этот бит устанавливается обработчиком команды, когда физическое устройство занято выполнением предыдущей операции и поэтому не может выполнить требуемую команду. Этот бит используется также для передачи такой информации, как "буфер клавиатуры не пуст", "среда носителя данных заменяемая" (в команде проверки возможности замены среды носителя данных).
10-14 Зарезервировано.
15 Признак ошибки. Устанавливается драйвером, когда он не может обработать запрос или произошла физическая либо логическая ошибка при обработке правильного запроса. Биты 0-7 при этом должны содержать код ошибки.
Приведем таблицу возможных кодов ошибок:

Код Описание
0 Нарушение защиты от записи. Была предпринята попытка записи информации на защищенное от записи устройство.
1 Неизвестное устройство.
2 Устройство не готово.
3 Неизвестная команда. Затребованная команда не поддерживается драйвером.
4 Ошибка CRC. При выполнении команды обнаружена ошибка циклического кода проверки.
5 Неправильная длина запроса. Поле длины в заголовке запроса содержит неверное значение.
6 Ошибка при поиске дорожки (дорожка не найдена).
7 Неизвестный носитель данных.
8 Сектор не найден.
9 Нет бумаги в принтере.
0Ah Ошибка записи.
0Bh Ошибка чтения.
0Ch Общая ошибка.
0Dh Зарезервировано.
0Eh Зарезервировано.
0Fh Неразрешенная замена диска (только для DOS версии 3.0 и более поздних версий).
<


Общая схема действий программы прерывания драйвера такова:

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


  • при необходимости программа считывает дополнительную информацию из области запроса;


  • затребованная команда выполняется (если она поддерживается драйвером);


  • если драйвер считывает какие-либо данные от обслуживаемого физического устройства для передачи их DOS, то сами данные или их адреса программа прерывания записывает в область запроса;


  • программа прерывания устанавливает слово состояния устройства в соответствии с результатами выполнения команды (если драйвер не поддерживает затребованную команду, в слове состояния устройства устанавливаются биты 15 и в биты 0-7 записывается код ошибки 3 - неизвестная команда);


  • восстанавливается содержимое регистров процессора, и управление возвращается операционной системе с помощью команды возврата из дальней процедуры.


  • Приведем фрагмент исходного текста программы прерывания, который выполняет описанные выше функции:

    interrupt_proc:

    push es ;сохраняем регистры push ds push ax push bx push cx push dx push si push di push bp

    ; Устанавливаем ES:BX на заголовок запроса

    mov ax,cs:req_seg mov es,ax mov bx,cs:req_off

    ; Загружаем в регистр AL код команды из заголовка ; запроса и умножаем его на 2 для получения индекса ; в таблице адресов команд

    mov al,es:[bx]+2 shl al,1

    sub ah,ah ;обнуляем AH lea di,functions ;DI содержит смещение таблицы ; команд add di,ax ;добавляем смещение jmp word ptr [di] ;переходим по адресу, взятому ; из таблицы

    functions LABEL WORD ;это таблица функций

    dw initialize dw check_media dw make_bpb dw ioctl_in dw input_data dw nondestruct_in dw input_status dw clear_input dw output_data dw output_verify dw output_status dw clear_output dw ioctl_out dw Device_open dw Device_close dw Removable_media

    ;---выход из драйвера, если функция не поддерживается

    check_media: make_bpb: ioctl_in: nondestruct_in: input_status: clear_input: output_verify: output_status: clear_output: ioctl_out: Removable_media:



    ; Если функция не поддерживается драйвером, устанавливаем ; в единицу биты 15 (ошибка), 8 (выполнение команды ; завершено). В биты 0-7 записываем код ошибки 3 - ; неизвестная команда.

    or es:word ptr [bx]+3,8103h jmp quit

    ;=======================================================

    ; Это пример обработчика команды:

    Device_open:

    ; . . . . . . . . . . ; Некоторые действия для открытия устройства. ; . . . . . . . . . .

    jmp quit

    ;=======================================================

    ;---выходим, модифицируя байт состояния status в заголовке ; запроса

    quit:

    or es:word ptr [bx]+3,100h ;устанавливаем бит 8 ;(выполнение команды ;завершено)

    pop bp ;восстанавливаем регистры pop di pop si pop dx pop cx pop bx pop ax pop ds pop es ret

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


    Содержание раздела