Таблица 8



Таблица 8

(0) 2sect_sizКоличество байтов в одном секторе диска.
(+2) 1clustsizКоличество секторов в одном кластере.
(+3) 2res_sectКоличество зарезервированных секторов.
(+5) 1fat_cntКоличество таблиц FAT.
(+6) 2root_sizМаксимальное количество дескрипторов файлов, содержащихся в корневом каталоге диска.
(+8) 2tot_sectОбщее количество секторов на носителе данных (в разделе DOS).
(+10) 1mediaБайт-описатель среды носителя данных.
(+11) 2fat_sizeКоличество секторов, занимаемых одной копией FAT.

Подробно формат и назначение полей BPB будут описаны в разделе, посвященном файловой системе DOS.

Приведем фрагмент исходного текста драйвера, возвращающего при инициализации указатель на массив BPB: lea dx,bpb_ptr mov es:[bx+18],dx mov es:[bx+20],cs . . . . . . . . . .

В этом примере предполагается, что ES:BX содержит адрес заголовка запроса.

Область данных может содержать, например, такое описание bpb_ptr: bpb: DW 512 ; количество байтов на сектор DB 1 ; количество секторов на кластер DW 1 ; зарезервировано секторов DB 2 ; количество копий FAT DW 64 ; максимальное количество файлов ; в корневом каталоге DW 360 ; общее число секторов на диске DB 0FCh ; описатель среды DW 2 ; количество секторов в FAT ; bpb_ptr DW bpb ; таблица для трех одинаковых DW bpb ; логических устройств DW bpb

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

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

Драйвер символьного устройства при этом может указать в качестве конечного адреса резидентной части программы адрес начала драйвера, т.е. адрес заголовка драйвера. Размер резидентной части при этом будет равен нулю.

Блочные драйверы дополнительно должны записать ноль в поле количества обслуживаемых логических устройств n_units.

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

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

Исходный текст драйвера: .MODEL tiny .CODE ; Драйвер состоит из одного ; сегмента кода org 0 ; Эта строка может отсутствовать include sysp.inc ;======================================================== simple PROC far ; Драйвер - это FAR-процедура ;======================================================== E_O_P: ;Метка конца программы, ;устанавливаем ее в начало ;драйвера, т.к. не надо ;оставлять драйвер резидентно ;в памяти ; Заголовок драйвера dd 0ffffffffh ;адрес следующего драйвера dw 8000h ;байт атрибутов dw dev_strategy ;адрес процедуры стратегии dw dev_interrupt ;адрес процедуры прерывания db 'SIMPLE_D' ;имя устройство (дополненное ;пробелами) ;======================================================== ; Программа стратегии dev_strategy: mov cs:req_seg,es mov cs:req_off,bx ret ; Здесь запоминается адрес заголовка запроса req_seg dw ? req_off dw ? ;======================================================== ;Обработчик прерывания dev_interrupt: 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 ; Получаем код команды из заголовка запроса и умножаем ; его на два, чтобы использовать в качестве индекса ; таблицы адресов обработчиков команд 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: Device_open: Device_close: output_data: input_data: or es:word ptr [bx]+3,8103h jmp quit ;======================================================== quit: or es:word ptr [bx]+3,100h pop bp pop di pop si pop dx pop cx pop bx pop ax pop ds pop es ret ;======================================================== ; Процедура выводит на экран строку ; символов в формате ASCIIZ dpc proc near push si dpc_loop: cmp ds:byte ptr [si],0 jz end_dpc mov al,ds:byte ptr [si] @@out_ch al inc si jmp dpc_loop end_dpc: pop si ret dpc endp ;======================================================== hello db 13,10,'+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+' db 13,10,'¦ *SIMPLE* (C)Frolov A., 1990 ¦' db 13,10,'+­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­+' db 13,10 db 13,10,'Hit any key...' db 13,10,0 ;======================================================== initialize: lea ax,E_O_P ;смещение конца программы в AX mov es:word ptr [bx]+14,ax ;помещаем его в заголовок mov es:word ptr [bx]+16,cs ; ; Стираем экран mov dh,18h mov dl,80h xor cx,cx mov bh,7 xor al,al mov ah,6 int 10h ; Устанавливаем курсор в левый верхний угол экрана mov bh,0 xor dx,dx mov ah,2 int 10h ; Выводим сообщение mov ax,cs mov ds,ax mov si,offset hello call dpc ; Ожидаем нажатия на любую клавишу mov ax,0 int 16h jmp quit simple ENDP END simple

В программе используется макро @@out_ch, описанное в файле sysp.inc и предназначенное для вывода символов на экран дисплея. Файл sysp.inc имеется на дискете, прилагающейся к книге. Приведем текст макро @@out_ch: @@out_ch MACRO c1,c2,c3,c4,c5,c6,c7,c8,c9,c10 mov ah,02h IRP chr,<c1,c2,c3,c4,c5,c6,c7,c8,c9,c10> IFB <chr> EXITM ENDIF mov dl,chr int 21h ENDM ENDM

Текст этого драйвера транслировался при помощи ассемблера, входящего в состав QuickC 2.01. Полученный объектный модуль обрабатывался пакетным файлом: link %1.obj; exe2bin %1.exe %1.sys

Вы можете также использовать макроассемблер MASM версии 5.0 или более поздней версии.

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

Для испытания этого и других драйверов запишите драйвер в корневой каталог системной дискеты (с которой можно загрузить операционную систему) и поместите в файл CONFIG.SYS, находящийся на этой дискете строку: DEVICE=a:\simple.sys

Когда Ваш драйвер будет отлажен, его можно переписать на диск и подключить к файлу CONFIG.SYS, находящемуся на диске С:.



- Начало - - Назад - - Вперед -