|
2. |
Ход работы. |
||
|
2.1. Создание и синтаксическая отладка драйвера |
|||
|
2.1.1. |
|
||
|
|
Изучим содержимое файлов DRIVER.asm (программы драйвера) и TEST.asm (те- |
||
|
стовой программы отладки драйвера). |
|||
|
|
DRIVER.asm: |
||
|
|
|
|
|
1 |
|
;******************************************************************************* |
|
|
2 |
|
; |
Учебный драйвер символьного устройства |
|
3 |
|
;******************************************************************************* |
|
|
4 |
|
CSEG |
SEGMENT PARA PUBLIC 'CODE' |
|
|
|
|
|
|
5ORG 0
6 |
DR |
PROC FAR |
|
|
|
7ASSUME CS:CSEG, DS:CSEG, ES:CSEG
8 PUBLIC DEV_INT,DEV_STRATEGY,INITIALIZATION,OPEN,CLOSE,OUTPUT,END_OF_PROG
Драйвер устройства создаётся в формате, похожем на СОМ файл. Однако в отличие от СОМ файла в начало программы не нужно включать директиву ОRG 100Н для пропуска префикса программного сегмента. Вместо этого либо записывается ОRG 0, либо вообще ничего не пишется.
|
|
|
Драйвер описан как далекая (fаr) процедура и начинается с заголовка драйвера: |
|
41 |
|
;******************************************************************************* |
|
|
42 |
|
; |
Заголовок устройства DOS |
|
|
|
|
|
|
43;*******************************************************************************
44;
45 |
NEXT_DEV |
DD |
−1 |
46 |
ATTRIBUTE |
DW |
0C800H |
47 |
STRATEGY |
DW |
DEV_STRATEGY |
48 |
INTERRUPT |
DW |
DEV_INT |
49 |
DEV_NAME |
DB |
'TEST_DRV' |
50 |
; |
|
|
|
|
|
|
4
1.Первое поле (DD) всегда содержит значение -1, и когда МS DОS загружает драй-
вер, то оно заменяется на стартовый адрес следующего драйвера.
2.Второе поле — это слово (DW) атрибутов драйвера. Каждый бит слова отвечает за ту или иную особенность устройства. Имеем
0C80016 = 11001000000000002
Пользуясь таблицей для символьного драйвера (Рис. 2.1) определяем, что это сим-
вольное устройство (бит 15), поддерживающее функции IOCTL (14 бит). Поддер-
живающее функции OPEN/CLOSE (бит 11).
3.Третье поле содержит смещение для процедуры стратегии (DW) устройства.
4.Четвертое поле содержат смещение для процедуры обработки прерывания (DW).
5.Пятое поле содержит имя устройства. В данном случае, "TEST_DRV".
Рис. 2.1
5
Структуры фиксированной части заголовка запроса и заголовков запросов команд 8
и 13:
10 ;*******************************************************************************
11 |
; |
Структуры заголовков запроса |
12;*******************************************************************************
13;
14 |
RH |
STRUC |
; Фиксированная часть заголовка для любой команды |
15 |
RH_LEN |
DB |
? |
16 |
RH_UNIT |
DB |
? |
17 |
RH_CMD |
DB |
? |
18 |
RH_STATUS |
DW |
? |
19 |
RH_RES1 |
DD |
? |
20 |
RH_RES2 |
DD |
? |
21 |
RH |
ENDS |
|
22 |
; |
|
|
23 |
RH0 |
STRUC |
; Структура заголовка для команды 0 |
24 |
RH0_RH |
DB |
SIZE RH DUP(?) |
25 |
RH0_NUNITS |
DB |
? |
26 |
RH0_BRK_OFS |
DW |
? |
27 |
RH0_BRK_SEG |
DW |
? |
28 |
RH0_BPB_TBO |
DW |
? |
29 |
RH0_BPB_TBS |
DW |
? |
30 |
RH0_DRV_LTR |
DB |
? |
31 |
RH0 |
ENDS |
|
32 |
; |
|
|
33 |
RH8 |
STRUC |
; Структура заголовка для команды 8 |
34 |
RH8_RH |
DB |
SIZE RH DUP(?) |
35 |
RH8_MEDIA |
DB |
? |
36 |
RH8_BUF_OFS |
DW |
? |
37 |
RH8_BUF_SEG |
DW |
? |
38 |
RH8_COUNT |
DW |
? |
39 |
RH8 |
ENDS |
|
6
Область данных драйвера:
51 |
|
;******************************************************************************* |
|
||
|
|
||||
52 |
|
; |
Область данных драйвера |
|
|
53 |
|
;******************************************************************************* |
|
||
54 |
|
RH_OFF |
DW |
? |
|
55 |
|
RH_SEG |
DW |
? |
|
56 |
|
MSG |
DB |
'THIS IS DOS−DRIVER' |
|
57 |
|
|
DB |
0DH,0AH,07H,'$' |
|
58 |
|
BUFF |
DB |
0,0,0,0,0 ;Тестовый буфер |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Процедура стратегия: |
|
89 |
|
;******************************************************************************* |
|
|
90 |
|
; |
Процедура СТРАТЕГИЯ |
|
91;*******************************************************************************
92;
93DEV_STRATEGY:
94 |
MOV |
CS:RH_SEG, |
ES |
95 |
MOV |
CS:RH_OFF, |
BX |
|
|
|
|
96RET
97;
Задача программы стратегии - запомнить адрес заголовка запроса в области памяти драйвера, в его внутренни переменных. Через пару регистров ES:BX драйверу переда-
ется адрес заголовка запроса.
|
|
|
Процедура прерывание: |
|
97 |
|
;******************************************************************************* |
|
|
98 |
|
; |
Процедура ПРЕРЫВАНИЕ |
|
|
|
|
|
|
99;*******************************************************************************
100;
101DEV_INT:
102PUSH DS
103PUSH ES
104PUSH AX
105PUSH BX
7
106PUSH CX
107PUSH DX
108PUSH DI
109PUSH SI
110;
111 |
MOV |
AX,CS:RH_SEG |
112 |
MOV |
ES,AX |
113 |
MOV |
BX,CS:RH_OFF |
114 |
; |
|
115 |
MOV |
AL,ES:[BX].RH_CMD |
116 |
SHL |
AL,1 |
117 |
LEA |
DI,CS:CMD_TAB |
118 |
MOV |
AH,0 |
119 |
ADD |
DI,AX |
120 |
JMP |
WORD PTR[DI] |
121 |
; |
|
|
|
|
К процедуре прерывания MS DOS обращается уже после обращения к процедуре стратегии. В обработчике прерывания программа сохраняет содержимое всех регистров.
Затем считываем номер команды из заголовка запроса. Команда выполняется.
|
|
|
Выход: |
|
182 |
|
;******************************************************************************* |
|
|
183 |
|
; |
Выход |
|
184;*******************************************************************************
185;
186ERROR_EXIT:
187 MOV ES:[BX].RH_STATUS,8103H
188 |
JMP |
EXIT |
|
|
|
189;
190SUCCESS_EXIT:
191 |
MOV |
ES:[BX].RH_STATUS,0100H |
192 |
EXIT: |
|
193 |
POP |
SI |
194 |
POP |
DI |
|
|
|
8
195 |
POP |
DX |
196 |
POP |
CX |
197 |
POP |
BX |
198 |
POP |
AX |
199 |
POP |
ES |
200 |
POP |
DS |
201RET
202;
203END_OF_PROG:
204 |
DR |
ENDP |
205 |
CSEG |
ENDS |
206 |
|
END |
|
|
|
Выполнив команду, программа переходит к выходу, где устанавливает слово состо-
яния. При ошибке записывается 1 в 15 бите, при успешном - 1 в 8 бит. Затем восстанав-
ливается содержимое всех регистров.
|
|
|
Команды, поддерживаемые рассматриваемым драйвером: |
|
137 |
|
;******************************************************************************* |
|
|
138 |
|
; |
Обработка команд DOS |
|
|
|
|
|
|
139;*******************************************************************************
140;
141 |
INITIALIZATION: |
; 0 − Инициализация |
142 |
CALL |
INIT |
143 |
LEA |
AX,END_OF_PROG |
144 |
MOV |
ES:[BX].RH0_BRK_OFS,AX |
145 |
MOV |
ES:[BX].RH0_BRK_SEG,CS |
146 |
JMP |
SUCCESS_EXIT |
|
|
|
Инициализация должна поддерживаться любым драйвером, так как она сообщает опе-
рационной системе сведения, необходимые MS DOS для правильного подключения и использования драйвера. Выполняется всегда после загрузки драйвера и только один раз. Должна возвращать логический адрес конца драйвера. При инициализации драй-
вер символьного устройства может получать из заголовка запроса (поле со смещением
18) и сохранять в своей внутренней области данных параметры инициализации из файла
9
config.sys.
Текущая процедура вызывает INIT:
126 |
INIT |
PROC NEAR |
|
127 |
|
PUSH |
DS |
128 |
|
MOV |
AX,CS |
129 |
|
MOV |
DS,AX |
130 |
|
LEA |
DX,CS:MSG |
131 |
|
MOV |
AH,9 |
132 |
|
INT |
21H |
133 |
|
POP |
DS |
|
|
|
|
134RET
135INIT ENDP
Которая выводит "THIS IS DOS-DRIVER" (см. область данных драйвера, строка 56).
Процедуры открытия и закрытия устройства, а также записи данных в буфер:
148 |
|
OPEN: |
; 13 |
− Открытие устройства |
|
|
|
||||
149 |
|
CLOSE: |
; 14 |
− Закрытие устройства |
|
150 |
|
JMP |
SUCCESS_EXIT |
|
|
151 |
|
|
|
|
|
152 |
|
OUTPUT: |
; 8 − Вывод |
|
|
153 |
|
; Выполнить запись данных в тестовый буфер BUFF |
|
||
154 |
|
JMP |
SUCCESS_EXIT |
|
|
|
|
|
|
|
|
10
Теперь изучим содержимое файла TEST.asm:
1 |
;**************************************************************************** |
||
2 |
; |
Тестовая программа для отладки символьного драйвера устройства |
|
3 |
;**************************************************************************** |
||
4 |
; |
|
|
5 |
STACK |
SEGMENT PARA |
STACK 'STACK' |
|
|
|
|
6DB 128 DUP(0)
7 |
STACK |
ENDS |
|
8 |
; |
|
|
9 |
; |
|
|
10 |
DSEG |
SEGMENT PARA PUBLIC |
'DATA' |
11 |
DEVICE |
DB 'TEST_DRV',0 |
; Имя устройства |
12 |
HANDL |
DW 0 |
; Номер устройства |
13 |
BUFF |
DB 1,2,3,4,5 |
; Тестовый буфер данных |
14 |
DSEG |
ENDS |
|
15 |
; |
|
|
16 |
CSEG |
SEGMENT PARA PUBLIC |
'CODE' |
17 |
|
ASSUME CS:CSEG, DS:DSEG, SS:STACK |
|
18 |
|
|
|
|
|
|
|
19BEGIN:
20MOV AX,DSEG
21MOV DS,AX
22
23 ; Открыть файл ( устройство )
24MOV DX,OFFSET DEVICE
25MOV AL,2
26MOV AH,3DH
27INT 21H
28 |
MOV HANDL,AX |
;Точка останова B1 |
29 |
|
|
30 |
; Вывести в файл ( в устройство ) тестовый буфер |
|
|
|
|
31MOV BX,HANDL
32MOV DX,OFFSET BUFF
11
33MOV CX,5
34MOV AH,40H
35INT 21H
36 |
|
|
37 |
; Закрыть файл ( устройство ) |
|
38 |
MOV BX,HANDL |
; Точка останова B2 |
39 |
MOV AH,3EH |
|
40 |
INT 21H |
|
41 |
|
|
42 |
; Выход из программы |
|
|
|
|
43MOV AH,4CH
44INT 21H
45 |
|
|
46 |
CSEG |
ENDS |
47 |
|
END BEGIN |
Здесь происходит тестирование всех поддерживаемых команд драйвера.
Для открытия используется функция 3DH и прерывание 21H (функция OPEN) драй-
вера). Вывод - функция 40H (OUTPUT для драйвера). 3EH для закрытия (CLOSE для драйвера).
2.1.2.
Ознакомимся с форматом командных строк макроассемблера (Рис. 2.4, Рис. 2.5). На Рис. 2.2 и 2.3 приведено содержание файлов DRIVER.bat и TEST.bat, находящихся в директории C:\DRIVER.
Рис. 2.2. Содержимое driver.bat
Рис. 2.3. Содержимое test.bat
12
Рис. 2.4. MASM
Рис. 2.5. LINK
2.1.3.
Создадим исполняемые файлы драйвера DRIVER.SYS и тестовой программы TEST.EXE,
проконтролировав возможные синтаксические ошибки в файлах листинга (*.LST). Пред-
варительно потребовалось переместить masm и exetobin в директорию C:\DRIVER.
C:\DRIVER>masm driver, driver, driver, null
C:\DRIVER>link /map driver, driver, driver, ,
C:\DRIVER>exetobin driver.exe driver.sys
C:\DRIVER>masm test, test, test, test
C:\DRIVER>link test, test, test, ,
13
