|
Politica de confidentialitate |
|
• domnisoara hus • legume • istoria unui galban • metanol • recapitulare • profitul • caract • comentariu liric • radiolocatia • praslea cel voinic si merele da aur | |
Drivere pentru dispozitive de I/O - Sisteme de operare | ||||||
|
||||||
t5v10vk Un sistem de operare este o colectie de programe care utilizeaza disponibilitatile hardware fara sa-l intereseze detaliile. De asemenea , un sistem de operare ce se executa pe un calculator trebuie sa se execute si pe un altul compatibil cu el (portabilitate). Totusi, sistemele de operare nu pot fi facute sa mearga pe absolut toate calculatoarele dintr-o anumita clasa. De aceea este nevoie pentru dispozitivele periferice de un anumit software specific pentru a efectua operatii cu ele - drivere de I/O. Exista o mare diversitate de dispozitive periferice datorita numarului mare de producatori. Sistemul de operare se interfateaza cu acest software specific dispozitivelor periferice inglobindu-l. Un sistem de operare trebuie sa asigure o interfata standard (environment) astfel ca programele ce se executa pe un calculator sa se poata executa pe un altul cu acelasi sistem de operare. Trebuie sa existe un API prin care sa se gestioneze fisierele si dispozitivele (device) din sistem. Avind aceasta, se redirecteaza pur si simplu intrarea sau iesirea in diverse programe. De exemplu, daca avem un program ce lucreaza cu fisiere si device-uri prin handlere, modificind numarul handlerului putem schimba preluarea caracterelor de la tastatura la interfata seriala sau fisier. Un driver pentru un dispozitiv de I/O este o suma de functiuni, un program care controleaza transferul din si inspre dispozitivul de I/O, fiind hardware dependent (instructiuni de I/O), facind legatura intre dispozitiv si sistemul de operare, fiind integrat sau nu in API sistem. Driverele de I/O pot fi : -de sistem (standard) -de aplicatie Driverele de sistem (standard) respecta o anumita structura pe cind cele de aplicatii sunt pur si simplu o suma a functiilor pentru gestiunea perifericului. De exemplu se pot scrie drivere pentru : imprimante noi, plottere, mouse-uri, canale A/D,D/A etc. De asemenea se poate inlocui driverul standard de tastatura cu unul propriu etc. MS-DOS permite inlocuirea sau adaugarea unor drivere urmatoarelor dispozitive standard de I/O : CON : Console input -Keyboard -software de comunicatii folosind intreruperile Driverele standard incarcate de DOS implicit sint cele pentru ecran, tastatura, imprimanta, disc si ceas. Antetul driverului contine deci : Offset Marime Continut 1 1 1 1 1 1 Offset Marime Continut Cele doua adrese (cod de strategie si intrerupere) sint prevazute pentru viitoare versiuni multitasking ale MS-DOS-ului, deoarece este evident ca operatiile de I/O cu dispozitvele periferice trebuie sa fie asincrone fata de cereri. Astfel subrutina cod de strategie va fi executata dind nastere la un sir al cererilor pentru operatiile de I/O cu dispozitivul periferic respectiv astfel ca driverul nu asteapta pina se efectueaza operatia respectiva dind controlul sistemului de operare. Este sarcina subrutinei cod de intrerupere, lansata imediat dupa de DOS, de a rezolva cererile din acest sir una cite una cind dispozitivul de I/O este pregatit. Cind o cerere este rezolvata subrutina cod de intrerupere semnalizeaza aceasta printr-un fanion de "Done". MS-DOS scaneaza periodic cererile lansate pentru dispozitivul respectiv si cind sesizeaza una din ele cu fanionul "Done" rezolva toata functia care solicita cererea respectiva. Deoarece aceste cereri apar aleatoriu este clar ca ele nu se pot transmite ca niste informatii in citeva registre sau variabile de memorie si trebuie transmise sub forma unei structuri standard de cerere numita cerere-pachet care este introdusa in sirul operatiilor ce urmeaza sa le efectueze driverul cu dispozitivul de I/O. Cererea pachet are doua parti : -un antet al cererii care este acelasi pentru toate cererile (13 octeti) Cererea pachet este transmisa driverului prin ES:BX Offset Marime Continut Cuvintul de stare returnat are structura : 1 1 1 1 1 1 -drivere caracter care difera intre ele prin informatiile ce le contin.Driverele caracter sint
cele care transfera octet cu octet informatia cu un dispozitiv de I/O. Driverele bloc transfera o informatie egala cu un bloc de octeti, de exemplu discurile
Exemplu 1 : driver pentru consola ;*********************************************************************; ;*-------------------------------------------------------------------*; ;* Task : Programul este un driver de consola *; ;* (Keyboard and Display Monitor). *; ;* Poate inlocui ANSI.SYS *; ;* *; ;*-------------------------------------------------------------------*; ;* tasm condrv; *; ;* tlink condrv; *; ;* exe2bin condrv condrv.sys *; ;*-------------------------------------------------------------------*; ;* Apel : DEVICE=CONDRV.SYS in CONFIG.SYS *; ;* *; ;*********************************************************************; code segment assume cs:code,ds:code,es:code,ss:code org 0 ;no PSP ;== Constants ========================================================= cmd_fld equ 2 ;Offset command field in data block status equ 3 ;Offset status field in data block end_adr equ 14 ;Offset driver end-adr. in data block num_db equ 18 ;Offset number in data block b_adr equ 14 ;Offset buffer address in data block KEY_SZ equ 20 ;Size of key board buffer num_cmd equ 16 ;Subfunctions 0-16 are supported ;== Data ============================================================== ;-- Header of Device Driver ------------------------------------------- dw -1,-1 ;Connection to next driver dw 1010100000000011b ;Driver attribute dw offset strat ;Pointer to strategy routine dw offset intr ;Pointer to interrupt routine db "CONDRV " ;new Console driver ;-- Jump Table for functions ------------------------- fct_tab dw offset init ;Function 0: Initialization dw offset dummy ;Function 1: Media Check dw offset dummy ;Function 2: Create BPB dw offset no_sup ;Function 3: I/O control read dw offset read ;Function 4: Read dw offset read_b ;Function 5: Non-dest. Read dw offset dummy ;Function 6: Input-Status dw offset del_in_b ;Function 7: Erase Input-Buffer dw offset write ;Function 8: Write dw offset write ;Function 9: Write & Verify dw offset dummy ;Function 10: Output-Status dw offset dummy ;Function 11: Erase Output-Buffer dw offset no_sup ;Function 12: I/O control write dw offset dummy ;Function 13: Open (starting at 3.0) dw offset dummy ;Function 14: Close dw offset dummy ;Function 15: changeable Medium dw offset write ;Function 16: Output until Busy db_ptr dw (?),(?) ;Address of data block passed key_a dw 0 ;Pointer to next character in KEY_SZ key_e dw 0 ;Pointer to last character in KEY_SZ key_bu db KEY_SZ dup (?) ;internal Keyboard Buffer ;== Routines and functions of driver =============================== strat proc far ;Strategy routine mov cs:db_ptr,bx ;Store address of data block in the mov cs:db_ptr+2,es ;Variable DB_PTR ret ;back to caller strat endp ;---------------------------------------------------------------------- intr proc far ;Interrupt routine push ax ;Store registers on the stack push bx push cx push dx push di push si push bp push ds push es pushf ;store also the flag register push cs ;Set data segment register pop ds ;Code is identical here with data les di,dword ptr db_ptr;Address of data block to ES:DI mov bl,es:adi+cmd_fldi ;Get command-code cmp bl,num_cmd ;is command-code permitted? jle bc_ok ;YES --> bc_ok mov ax,8003h ;Code for "unknown Command" jmp short intr_end ;back to caller ;-- Command-Code was o.k. --> Execute command ---------------- bc_ok: shl bl,1 ;Calculate pointer in jump table xor bh,bh ;erase BH call afct_tab+bxi ;Call function les di,dword ptr db_ptr;Address of the data block to ES:DI ;-- Execution of the function completed -------------------- intr_end label near or ax,0100h ;Set finished-bit mov es:adi+statusi,ax ;store everything in the status field popf ;Restore flag register pop es ;Restore other registers pop ds pop bp pop si pop di pop dx pop cx pop bx pop ax ret ;back to caller intr endp ;---------------------------------------------------------------------- dummy proc near ;This routine does nothing xor ax,ax ;Erase busy-bit ret ;back to caller dummy endp ;---------------------------------------------------------------------- no_sup proc near ;This routine called for all functions no_sup endp ;---------------------------------------------------------------------- store_c proc near ;stores a character in the internal mov abx+key_bui,al ;store character in internal buffer inc bl ;increment pointer to End cmp bl,KEY_SZ ;End of buffer reached ? jne store_e ;NO --> STORE_E xor bl,bl ;new end is the beginning of buffer store_e: ret ;back to caller store_c endp ;---------------------------------------------------------------------- read proc near ;read a certain number of characters mov cx,es:adi+num_dbi ;read number of characters jcxz read_e ;test if equal to 0 les di,es:adi+b_adri ;Address of character buffer to ES:DI cld ;on STOSB count up mov si,key_a ;Pointer to next character in KEY_SZ mov bx,key_e ;Pointer to last character in KEY_SZ read_1: cmp si,bx ;other characters in keyboard buffer? jne read_3 ;YES --> READ_3 read_2: xor ah,ah ;Function number for reading is 0 int 16h ;Call BIOS Keyboard-interrupt call store_c ;Store characters in internal buffer cmp al,0 ;test if extended code jne read_3 ;no --> READ_3 mov al,ah ;Extended Code is in AH call store_c ;store read_3: mov al,asi+key_bui ;read character from keyboard buffer stosb ;transmit to buffer of calling funct. inc si ;Increment pointer to next character cmp si,KEY_SZ ;End of buffer reached? jne read_4 ;NO --> READ_4 xor si,si ;next character is the first character read_4: loop read_1 ;repeat until all characters read mov key_a,si ;Store position of the next character read_e: xor ax,ax ;everything o.k. ret ;back to caller read endp ;---------------------------------------------------------------------- read_b proc near ;read the next character from the mov ah,1 ;Function number for BIOS-interrupt int 16h ;call BIOS Keyboard-interrupt je read_p1 ;no character present --> READ_P1 mov es:adi+13i,al ;store character in data block xor ax,ax ;everything o.k. ret ;back to caller read_p1 label near mov ax,0100h ;Set busy-bit (no character) ret ;back to caller read_b endp ;---------------------------------------------------------------------- del_in_b proc near ;erase input buffer mov ah,1 ;Still characters in the buffer? int 16h ;Call BIOS key board interrupt je del_e ;no character in the buffer --> END xor ah,ah ;Remove character from buffer int 16h ;Call BIOS key board interrupt jmp short del_in_b ;Test for additional characters del_e: xor ax,ax ;everything o.k. ret ;back to caller del_in_b endp ;---------------------------------------------------------------------- write proc near ;write a specified number of mov cx,es:adi+num_dbi ;Number of characters read jcxz write_e ;test if equal to 0 lds si,es:adi+b_adri ;Address of character-buffer to DS:SI cld ;on LODSB increment count mov ah,3 ;read current display page int 16h ;Call BIOS Video-interrupt mov ah,14 ;Function number for BIOS interrupt write_1: lodsb ;read character to be output to AL int 10h ;call BIOS Video-interrupt loop write_1 ;repeat until all characters output write_e: xor ax,ax ;everything o.k. ret ;back to caller write endp ;---------------------------------------------------------------------- init proc near ;Initialization routine mov word ptr es:adi+end_adri,offset init ;Set End-Address of mov es:adi+end_adr+2i,cs ;the driver xor ax,ax ;everything o.k. ret ;back to caller init endp ;====================================================================== code ends end Exemplul 2: driver pentru seriala code segment assume cs:code,ds:code,es:code,ss:code org 0 commhdr: dw -1,-1 dw 8000h dw offset strategy dw offset intr db "comm " request equ 0 ;originea cererii pachet unit equ request+1 cmd equ unit+1 status equ cmd+1 doslink equ status+2 ;se depune de DOS adresa urmatoarei cereri queue db 2048 dup(?) ;zona buffer pt intr quein dw 0 ;index pt urmatorul caract receptionat queout dw 0 ;index al urmat caract trimis DOS-ului handler proc far interrupt: push ax ;salvare context push bx push cx push dx push si push di push ds push es push bp in al,status_port ;test stare seriala test al,2 jz intout in al,comm_port ;preluare caract push ax ;calculeaza urmat adresa unde vine depus caract mov ax,cs:quein inc ax and ax,2047 ;modulo 2048 mov cs:quein,ax mov bx,ax pop ax mov cs:queueabxi,al ;depune caract intout: mov al,20h ;clear interrupt out 20h,al sti ;rearmeaza intreruperile pop bp pop es pop ds pop di pop si pop dx pop cx pop bx pop ax iret handler endp jmptbl: dw comminit dw exit dw exit dw exit dw getchar dw lookchar dw getstat dw flusher dw exit dw exit dw exit dw exit dw exit savptr dd 0 ;se salveaza pointer trimis de DOS in ES:BX stratp proc far strategy: mov cs:word ptr savptr,bx mov cs:word ptr savptr+2,es ret stratp endp ops proc far intr: ;incep tratarea functiilor incluse in driver push si push ax push cx push dx push di push bp push ds push es push bx lds bx,cs:dword ptr savptr ;preia pointerul pasat de DOS assume ds : nothing xor ax,ax mov al,ds:byte ptr cmdabxi ;preia comanda mov si,offset jmptbl ;baza tabelei de functii add si,ax ;aduna offset add si,ax cmp al,11 ;am doar 11 functii din 24 ja exit mov cx,ds:word ptr countabxi ;preia nr de octeti de transferat les di,ds:dword ptr dtaabxi ;adresa bufferului push cs pop ds assume ds:code jmp asii exit: assume ds:nothing or ah,01h ;seteaza Done lds bx,cs:dword ptr savptr ;preia adresa cererii pachet din nou mov ds:word ptr statusabxi,ax ;retine starea pop bx pop es pop ds pop bp pop di pop dx pop cx pop ax pop si ret getchar: mov ax,cs:queout ;preia indexul de trimis cmp ax,cs:quein ;compara cu indexul de receptie je getchar ;asteapta daca nu am caract mov dx,0 getone: inc dx ;tine socoteala transferului de octeti inc ax ;incr indexul de trimis DOS-ului and ax,2047 ;modulo 2048 mov bx,ax ;salveaza indexul mov al,cs:queueabxi ;preia caract din bufferul driverului stosb ;depune caract in bufferul aplicatiei mov ax,bx ;refa cmp ax,cs:quein ;test cu indexul de receptie loopne getone gotlast: mov cs:queout,ax lds bx,cs:dword ptr savptr mov ds:word ptr countabxi,dx ;salveaza contorul final xor ax,ax ;sterge erorile jmp exit ;se termina transferul lookchar: ;citire fara preluare din buffer mov ax,queout inc ax and ax,2047 mov si,ax mov al,queueasii push ds lds bx,dword ptr savptr ;preia adresa cererii DOS mov ds:abxi.char,al ;salveaza caract intr-un loc anume pop ds xor ax,ax jmp exit getstat: ;seteaza Busy daca ambii indexi sint egali mov ax,queout cmp ax,quein je setbusy xor ax,ax ;am caract de preluat jmp exit setbusy: mov ax,0200h ;seteaza Busy jmp exit flusher: ;goleste continutul bufferului driverului xor ax,ax mov quein,ax mov queout,ax jmp exit In continuare dam un exemplu simplu de folosire a driverului comm, utilizat ca un fisier. Driverul este deschis si se citesc caractere. O tratare mai complexa ar include deschiderea, citirea, scrierea, iesirea din cicluri de citire/scriere, inchiderea. . 1. Care sint structurile de control implicate in descrierea unui driver standard 2. Ce completeaza programatorul si ce completeaza DOS-ul 3. Cum se produce efectiv trasferul dinspre si de la un periferic, avind in etapele DOS-driver-periferic si retur. 4. Analizati programele condrv.asm si comm.asm 5. Modificati programul comm.asm pentru a putea deveni un driver de seriala de transmisie-receptie, a putea controla initializarea parametrilor de comunicatie si a putea folosi ambele interfete seriale
|
||||||
|
||||||
|
||||||
Copyright© 2005 - 2024 | Trimite document | Harta site | Adauga in favorite |
|