Драйверы устройств в системе Windows

       

Драйвер устройства в системе MS-DOS


     На  листинге  1  показана  программа  dostest.asm, представляющая собой обычный драйвер устройства для системы MS-DOS, который  общается с устройством. Несмотря  на простоту и  малый размер данная  программа содержит   основные    компоненты   драйвера    устройства,    который обрабатывает прерывания.

_____________________________________________________________________

page ,132

; masm tisr ; >err

    .286p

.xlist

include ..\..\include\bogus.inc

.list

Words struc

LoWord dw ?

HiWord dw ?

Words ends

EOI equ 020h            ; команда EOI для контроллера PIC



INTA00 equ 020h         ; управление главным контроллером PIC

INTA01 equ 021h         ; регистр маски главного контроллера PIC

INT_MASTER_0 equ 08h         ;номер INT  главн. контроллера PIC

INTB00 equ 0A0h         ; управление подчиненным контроллером PIC

INTB01 equ 0A1h         ;регистр маски подчиненного контроллера  PIC

INT_SLAVE_0 EQU 70h         ; номер INT подчиненного контроллера PIC

;

; Установить переменные для нашего номера прерывания

;

ife (FAKE_IRQ GE 8)

INT_DEV equ (INT_MASTER_0+(FAKE_IRQ AND 7))

PIC00 equ INTA00

PIC01 equ INTA01

else

INT_DEV equ (INT_SLAVE_0+(FAKE_IRQ AND 7))

INT_MASK equ 1 SHL (FAKE_IRQ AND 7)

PIC00 equ INTB00

PIC01 equ INTB01

endif

CONST SEGMENT DWORD PUBLIC 'DATA'

sdNoBogus db 'I do not see the bogus device.',Odh,Oah,'$'

sdPrompt db Odh,Oah,'S)tart, or Q)uit: ','$'

sdCRLF  db Odh,Oah,'$'

sdDot  db '.','$'

CONST ENDS

DATA SEGMENT DWORD PUBLIC 'DATA'

dwCount1 dw 0

dwCount2 dw 0

lpPrevISR dd 0           ; адрес предыдущей программы ISR

fStopping db 0           ; значение TRUE при завершении

DATA ENDS

STACK SEGMENT DWORD STACK 'STACK'

    db  512 dup (?)

STACK ENDS

DGroup GROUP CONST,DATA,STACK

;IP IntSvcRtn - The Interrupt Service Routine (Программа

обслуживания

;                                              прерывания)

;   WARNINGS (предупреждения)

;




;   NOTES (примечания)

; Данная программа ISR увеличивает счетчик прерываний (dwCount1)

; и заново маскирует устройство.

;

; Если установлен флаг "fStopping", устройство не маскируется заново.

;

FIXED_TEXT SEGMENT PARA PUBLIC 'CODE'

segData1     dw  DGroup

    assume  CS:FIXED_TEXT,DS:NOTHING

IntSvcRtn  proc far

    push     ax

    push     dx

    push     ds

    mov ds,segDatal

    assume ds:DGroup

    inc dwCount1

    mov al,NOT FAKE_CTL_EOI

    mov dx,FAKE_PORT

    out dx,al             ; послать EOI устройству

    mov al,EOI

    out PIC00,al          ; послать EOI контроллеру PIC

ife (PIC00 EQ INTA00)

    out INTA00,al         ; послать EOI главн. контроллеру PIC также

endif

    cmp fStopping,0       ; существует?

    jnz isr9              ; если да, то не нужен перезапуск

    mov al,NOT FAKE_CTL_START

    mov dx,FAKE_PORT

    out dx,al             ; перезапуск ввода-вывода

isr9:

    pop ds

    assume  ds:NOTHING

    pop dx

    pop ax

    iret

IntSvcRtn endp

FIXED_TEXT ENDS

;IP_main - точка входа в программу

;    NOTES (примечания)

;    Драйвер    устройства   выдает  для  пользователя   приглашение:

;S)tart(начать)  или  Q)uit(выйти).  Если   пользователь  нажимает S,

;программа разрешает прерывания и вооружает устройство, печатая точку

;каждый раз, как устройство прерывается.

;

_TEXT SEGMENT PARA PUBLIC 'CODE'

segData2     dw  DGroup

segfixed     dw  FIXED_TEXT

    assume  cs:_TEXT,ds:NOTHING

_main label far

    mov ds,segData2   ;инициализируется сегмент данных по умолчанию

    assume ds:DGroup

    mov dx,FAKE_PORT

    in  al,dx              ; присутствует ли фиктивное устройство?

    or  al,al

    jns m10          ;пропустить, если да

    mov dx,OFFSET DGroup:sdNoBogus

    mov ah,9

    int 21h      ; в противном случае печатать сообщение об ошибке

    mov ax,4C01h

    int 21h          ; и выйти из системы

m10:

    mov ax,3500h+INT_DEV



    cli

    int 21h          ; запросить текущую программу ISR

    mov lpPrevISR.LoWord,bx

    mov lpPrevISR.HiWord,es  ; сохранить ее

    mov dx,OFFSET FIXED_TEXT:IntSvcRtn

    push   ds

    mov ds,segFixed

    assume  ds:NOTHING

    mov ax,2500h+INT_DEV

    int 21h              ; установить нашу программу ISR

    pop ds

    assume  ds:DGroup

    sti

    mov dx,OFFSET DGroup:sdPrompt

    mov ax,9

    int 21h              ; S)tart или Q)uit

ml1:

    mov dl,0PFh

    mov ah,6

    int 21h              ; читать с консоли, не ожидая

    jz  ml3

    or  al,40h

    cmp al,'q'

    je  ml8              ; пропустить, если нажато "Q"

    cmp al,'s'

    jne ml3              ; пропустить, если не нажато "S"

    cli

    in  al,PIC01         ; размаскировать прерывание

    and al,NOT INT_MASK

    out PIC01,al

    sti

    mov al,NOT FAKE_CTL_START

    mov dx,FAKE_PORT

    out dx,al             ; начать ввод-вывод с устройства

ml3:

    mov ax,dwCount1

    cmp ax,dwCount2

    je  ml4      ; пропустить, если счетчик прерываний не изменился

    mov dwCount2,ax

    mov dx,OFFSET DGroup:sdDot

    mov ah,9

    int 21,h         ;в противном случае выдать точку

ml4:

    jmp ml1          ; цикл

ml8:

    mov fStopping,1     ; указание для программы ISR завершить работу

    mov dx,FAKE_PORT

ml9:

    in  al,dx

    rcr al,1

    jnc ml9          ; цикл, если занято

    cli

    in  al,PIC01

    or  al,INT_MASK

    out PIC01,al     ; маскировать уровень прерывания

    sti

    push    ds

    lds dx,lpPrevISR

    assume ds:NOTHING

    mov ax,2500h+INT_DEV

    int 21h           ; восстановить предыдущую программу ISR

    pop ds

    assume ds:DGroup

    mov ax,4C00h

    int 21h           ; выход

_TEXT ENDS

    end_main

_____________________________________________________________________

     Листинг 1. Программа dostest.asm

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


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

     Далее драйвер  устройства выдает  приглашение для  пользователя : Start(начать)  или   Quit(выйти).  Если   пользователь  нажимает    S, программа начинает пересылку ввода-вывода. Если пользователь  нажимает Q,  то   программа  отключает   устройство,  восстанавливает    вектор прерывания и завершается.

    Чтобы  начать  операцию  ввода-вывода,  драйвер  MS-DOS   сначада размаскирует  программируемый   контроллер  прерываний   (programmable interrupt  controller  -  PIC)  для  уровня  прерывания  устройства (в примере прерывание 11).  Затем драйвер начинает  операцию ввода-вывода для  устройства  путем  записи  1  в  бит  0 порта управления. Так как прерывания  включены,  то  при  возникновении прерываний на устройстве получит  управление  программа   обслуживания  прерываний   (interrupt service routine - ISR).

     Если  происходит  прерывание  на  устройстве,  то  программа  ISR подтверждает прием прерывания,  посылая значение EOI  устройству (т.е. записывая 1 в  бит 1 порта  управления устройства) и  контроллеру PIC. Если программа, выполняющая  ввод-вывод, существует, то  программа ISR выполняется.   В   противном   случае   программа   ISR   осуществляет инициализацию пересылки ввода-вывода вновь, записывая 1 в бит 0  порта управления  устройства.  Итак,  программа  ISR возобновляет ввод-вывод всякий  раз,  когда  происходит  прерывание,  таким образом устройство непрерывно   выполняет   операцию   ввода-вывода.   Кроме  обеспечения непрерывного ввода-вывода программа ISR увеличивает счетчик (dwCount1) всякий раз, когда обрабатывает прерывание.

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

     Чтобы  завершить  программу,  пользователь  нажимает  клавишу  Q.Программа  устанавливает  флаг,  который  информирует  программу ISR о том,  что  следует  остановить  обработку.  После  того,  как операция ввода-вывода  остановлена,  программа  маскирует  уровень прерывания в контроллере PIC и восстанавливает вектор прерывания.


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