Vanore C. Perusi D. Carpentieri M. 4F 17/04/07 I Driver In informatica, è detto driver l'insieme di procedure, spesso scritte in assembly, che permette ad un sistema operativo di pilotare un dispositivo hardware. Il driver permette al sistema operativo di utilizzare l'hardware senza sapere come esso funzioni, ma dialogandoci attraverso un'interfaccia standard, i registri del controllore della periferica, che astrae dall'implementazione dell'hardware e che ne considera solo il funzionamento logico. In questo modo hardware diverso costruito da produttori diversi può essere utilizzato in modo intercambiabile. Ne consegue che un driver è specifico sia dal punto di vista dell'hardware che pilota, sia dal punto di vista del sistema operativo per cui è scritto. Non è possibile utilizzare driver scritti per un sistema operativo su uno differente, perché l'interfaccia è generalmente diversa. Il driver è scritto solitamente dal produttore del dispositivo hardware, dato che è necessaria un'approfondita conoscenza dell'hardware per poter scrivere un driver funzionante. A volte, i driver vengono scritti da terze parti sulla base della documentazione tecnica rilasciata dal produttore, se questa è disponibile. Tipi di Driver Esistono driver di molti tipi, a secondo del tipo di hardware che devono pilotare e soprattutto del sistema operativo su cui devono girare. Nei sistemi embedded, in cui tutto il software è un unico programma compilato e caricato in ROM, il driver non è altro che una routine del programma che si interfaccia con l'hardware da pilotare. In maniera analoga, nei sistemi operativi con kernel monolitico, il driver è un modulo compilato insieme al kernel. Pertanto, non è possibile aggiungere una periferica nuova senza ricompilare il kernel. Nei sistemi operativi a microkernel, il driver è un file binario che viene caricato dinamicamente dal kernel. In questo caso è possibile aggiungere una nuova periferica e il kernel dovrà semplicemente caricare il file del driver opportuno. Struttura e funzionamento di un Driver Ogni driver deve risolvere il problema della mutua esclusione garantendo ad un solo processo (specie se il sistema è multiprocessore) l'accesso esclusivo alla periferica in ogni istante. A seconda di quanti processi potranno interagire direttamente con la periferica, può essere necessario introdurre un driver virtualizzato. Infatti, se ogni processo può agire sulla periferica in maniera indipendente dagli altri (si pensi ad un masterizzatore in fase di scrittura), fermo restando l'ipotesi di accesso esclusivo, si introduce un driver virtualizzato composto dai seguenti elementi: Procedura di acquisizione Procedura/e d'uso Procedura di rilascio Prima di chiamare le procedure d'uso, il processo deve acquisire l'uso esclusivo della periferica, e alla fine deve rilasciare la stessa agli altri processi. Il modello di sincronizzazione delle procedure d'uso è quello dei semafori inizializzati a rosso. Le procedure di acquisizione e rilascio, viceversa, sono le wait e signal di un semaforo virtuale associato alla periferica tale da garantire la mutua esclusione. Le procedure d'uso, come già accennato, seguono il modello dei semafori sempre rossi. Questo perché, data l'enorme differenza di velocità tra la CPU e la periferica, è necessario che il processo attenda la sincronizzazione delle operazioni con la periferica. Ciò avviene mediante gli interrupt Il driver fisico opera sui registri del controllore della periferica, in particolare su tre tipi registri fondamentali: Registro di controllo Registro di stato Registro dati Il primo è un registro in sola scrittura: il driver inserisce i dati relativi all'operazione richiesta. Solitamente è presente un bit di attivazione, impostato ad 1 alla fine del caricamento dei registri (quando cioè la periferica è pronta a partire), e azzerato dalla periferica al termine delle operazioni. Il registro di stato è un registro in sola lettura: al termine delle operazioni, la prima cosa da fare è verificare che la periferica non abbia restituito condizioni di errore. Il registro dati è un registro che può essere usato sia in lettura che in scrittura dalla CPU, in quanto viene usato per caricare i parametri di ingresso dell'operazione (es. che traccia leggere da disco) e può venire usato per leggere il risultato dell'operazione. Si noti che al posto di un unico registro dati può esistere una batteria di registri dati, il cui uso è documentato nel driver.