GESTIONE DELLE PERIFERICHE D INGRESSO/USCITA ARGOMENTI Compiti del sottosistema di I/O Architettura del sottosistema di I/O Gestore di un di I/O 1. Nascondere al programmatore i dettagli delle interfacce hardware dei dispositivi; 2. Omogeneizzare la gestione di dispositivi diversi; 3. Gestire i malfunzionamenti che si possono verificare durante un trasferimento di dati; 4. Definire lo spazio dei nomi (naming) con cui vengono identificati i dispositivi; 5. Garantire la corretta sincronizzazione tra un processo applicativo che ha attivato un trasferimento dati e l attività del. 1. Nascondere al programmatore i dettagli delle interfacce hardware dei dispositivi CPU Memoria Controllore di A Periferica A Controllore di B Periferica B bus 1) Omogeneizzare la gestione di dispositivi diversi velocità di trasferimento tastiera mouse modem linea ISDN stampante laser scanner porta USB disco IDE CD-ROM Fast Etherneet FireWire (IEEE 1394) monitor XGA Ethernet gigabit 10 bytes/sec 100 bytes/sec 10 Kbytes/sec 16 Kbytes/sec 100 Kbytes/sec 400 Kbytes/sec 1.5 Mbytes/sec 5 Mbytes/sec 6 Mbytes/sec 12.5 Mbytes/sec 50 Mbytes/sec 60 Mbytes/sec 125 Mbytes/sec 1
1) Omogeneizzare la gestione di dispositivi diversi TIPOLOGIE DI DISPOSITIVI Dispositivi a carattere (es. tastiera, stampante, mouse, ) Dispositivi a blocchi (es. dischi, nastri,..) Dispositivi speciali (es. timer) 1. Gestire i malfunzionamenti che si possono verificare durante un trasferimento di dati TIPOLOGIE DI GUASTI Eventi eccezionali (es. mancanza di carta sulla stampante, end-of-file ); Guasti transitori (es. disturbi elettromagnetici durante un trasferimento dati); Guasti permanenti (es. rottura di una testina di lettura/scrittura di un disco). 1. Definire lo spazio dei nomi (naming) con cui vengono identificati i dispositivi Uso di nomi unici (valori numerici) all interno del sistema per identificare in modo univoco i dispositivi; Uso di nomi simbolici da parte dell utente (I/O API Input/Output Application Programming Interface); Uniformità col meccanismo di naming del file-system. 1. Garantire la corretta sincronizzazione tra un processo applicativo che ha attivato un trasferimento dati e l attività del. Gestione sincrona dei trasferimenti: un processo applicativo attiva un e si blocca fino al termine del trasferimento; Gestione asincrona dei trasferimenti: un processo applicativo attiva un e prosegue senza bloccarsi; Necessità di gestire la bufferizzazione dei dati. 2
ARCHITETTURA DEL SOTTOSISTEMA DI I/O ARCHITETTURA DEL SOTTOSISTEMA DI I/O: parte dipendente dai dispositivi Interfaccia applicativa: I/O API Parte del sottosistema di I/O indipendente dai dispositivi Interfaccia device-independent Parte del sottosistema di I/O dipendente dai dispositivi: device drivers Disp. di rete disp. a blocchi disp. a carattere Parte dipendente dai dispositivi device drivers Interrupt handlers interfaccia di accesso ai dispositivi controllori dei dispositivi Livello sistema operativo Livello hardware ARCHITETTURA DEL SOTTOSISTEMA DI I/O: parte indipendente dai dispositivi LIVELLO INDIPENDENTE DAI DISPOSITIVI processi applicativi librerie interfaccia applicativa I/O API Parte I/O independent Livello utente Livello sistema operativo Naming Buffering FUNZIONI Gestione malfunzionamenti Allocazione dei dispositivi ai processi applicativi 3
BUFFERING Per ogni operazione di I/O il sistema operativo riserva un'area di memoria "tampone" (buffer), per contenere i dati oggetto del trasferimento. Motivazioni: differenza di velocita` tra processo e periferica: disaccoppiamento quantita` di dati da trasferire (es. dispositivi a blocchi): il processo puo` richiedere il trasferimento di una quantita` di informazioni inferriore a quella del blocco BUFFERING ES. operazione di lettura con singolo buffer lettura buffer sistema operativo Buffer: area tampone nella memoria del sistema operativo u-buf: area tampone nella memoria virtuale del processo applicativo copia u-buf processo applicativo BUFFERING ES. operazione di lettura con doppio buffer lettura buffer1 buffer2 sistema operativo copia u-buf processo applicativo GESTIONE MALFUNZIONAMENTI Tipi di gestione degli eventi anomali: Risoluzione del problema (mascheramento dell evento anomalo); Gestione parziale e propagazione a livello applicativo; Tipi di eventi anomali: Eventi propagati dal livello inferiore (es. guasto HW permanente; Eventi generati a questo livello (es. tentativo di accesso a un inesistente). 4
ALLOCAZIONE DEI DISPOSITIVI Dispositivi condivisi da utilizzare in mutua esclusione; Dispositivi dedicati ad un solo processo (server) a cui i processi client possono inviare messaggi di richiesta di servizio; LIVELLO DIPENDENTE DAI DISPOSITIVI Funzioni: fornire i gestori dei dispositivi (device drivers) offrire al livello superiore l insieme delle funzioni di accesso ai dispositivi (interfaccia device-independent ), es: N=_read (disp, buffer, nbytes) Tecniche di spooling (dispositivi virtuali). nome unico del Buffer di sistema GESTORE DI UN DISPOSITIVO Schema semplificato di un controllore GESTORE DI UN DISPOSITIVO Registri di stato e controllo comandi Reg. controllo segnali i s i: bit di abilitazione alle interruzioni CPU stato Reg. stato Registri di controllo s: bit di start dati Reg. dati controllore dati bus e f Registri di stato e: bit di condizioni di errore s: bit di flag 5
PROCESSO ESTERNO PROCESSO ESTERNO attende l invio di un comando tramite il registro di controllo esegue il comando segnala, tramite il registro di stato, la fine del comando Bit di start=0 bit di start 1 1 bit di flag processo esterno { while (true) { do{; while (start ==0)//stand-by <esegue il comando>; <registra l esito del comando ponendo flag = 1>; PROCESSO APPLICATIVO: gestione a controllo di programma PROCESSO APPLICATIVO Prepara un comando invia il comando attende la fine del comando no si fine 1 bit di start Bit di flag=0 bit di flag 1 processo applicativo { for (int i=0; i++; i<n) { <prepara il comando>; <invia il comando>; do{; while (flag ==0) //ciclo di attesa attiva <verifica l esito>; 6
GESTIONE A INTERRUZIONE Lo schema precedente viene detto anche a controllo di programma. Non adatto per sistemi multiprogrammati a causa dei clicli di attesa attiva. Per evitare l attesa attiva: Riservare, per ogni un semaforo: dato_disponibile (dato_disponibile = 0;) Attivare il abilitandolo a interrompere (ponendo nel registro di controllo il bit di abilitazione a 1). GESTIONE A INTERRUZIONE processo applicativo { for (int i=0; i++; i<n) { <prepara il comando>; <invia il comando>; p (dato_disponibile ) ; <verifica l esito>; commutazione di contesto FUNZIONE DI RISPOSTA ALLE INTERRUZIONI DIAGRAMMA TEMPORALE Interrupt_handler { v (dato_disponibile ) ; riattiva il processo applicativo Q PI inth PE PI: processo applicativo che attiva il PE: processo esterno Inth: routine di gestione interruzioni Q: altro processo applicativo 7
DIAGRAMMA TEMPORALE ASTRAZIONE DI UN DISPOSITIVO E` preferibile uno schema in cui il processo applicativo che ha attivato un per trasferire n dati venga risvegliato solo alla fine dell intero trasferimento: Q PI inth PE processi applicativi n= _read ( ) n= _write ( ) device driver descrittore del inth DESCRITTORE DI UN DISPOSITIVO indirizzo registro di controllo indirizzo registro di stato indirizzo registro dati semaforo Dato_disponibile contatore dati da trasferire puntatore al buffer in memoria esito del trasferimento DRIVER DI UN DISPOSITIVO ESEMPIO: int _read(int disp,char *buf,int cont) CON: la funzione che restituisce -1 in caso di errore o il numero di caratteri letti se tutto va bene, disp è il nome unico del, buf è l indirizzo del buffer in memoria, cont il numero di dati da leggere 8
DRIVER DI UN DISPOSITIVO int _read(int disp,char *buf,int cont) { descrittore[disp].contatore=cont; descrittore[disp].puntatore=buf; <attivazione > ; p(descrittore[disp].dato_disponibile); if (descrittore[disp].esito== <cod.errore>) return (-1); return (cont-descrittore[disp].contatore); DRIVER DI UN DISPOSITIVO void inth() //interrupt handler { char b; <legge il valore del registro di stato>; if (<bit di errore> == 0) {<ramo normale della funzione> else {<ramo eccezionale della funzione> return //ritorno da interruzione RAMO NORMALE DELLA FUNZIONE { < b = registro dati >; *(descrittore[disp].puntatore)= b; descrittore[disp].puntatore ++; descrittore[disp].contatore --; if (descrittore[disp].contatore!=0) <riattivazione >; else {descrittore[disp].esito = <codice di terminazione corretta>; <disattivazione >; v (descrittore[disp].dato_disponibile); RAMO ECCEZIONALE DELLA FUNZIONE { < routine di gestione errore >; if (<errore non recuperabile>) {descrittore[disp].esito = <codice di terminazione anomala>; v (descrittore[disp]. dato_disponibile); 9
Flusso di controllo durante un trasferimento Interfaccia applicativa Process PI { int n; int ubufsize = 64; char ubuf[ubufsize]; system call n=read(in, ubuf, ubufsize); 1 6 2 Sistema Operativo int read (device dp, char *punt, int cont){ int n, D; char buffer[n]; < individuazione del D coinvolto (naming)>; < controllo degli accessi>; n = _read(d, buffer, N); <trasferimento dei dati da buffer di sistema a ubuf>; return n; // ritorno da int. interfaccia device independent 5 CPU Gestione di un in DMA buffer puntatore buffer cont registro dati contatore Memoria cont DMA controllore 4 int _read (int disp, char *pbuf, int cont){ <attivazione del >; <sospensione del processo>; return (numero dati letti); void inth() { <trasferimento dati in buffer>; <riattivazione processo> 3 hardware 10