Uno dei molti vantaggi del Sistema Operativo Linux è che il suo “interno” è aperto a tutti. Il kernel Linux è un corpo grande e complesso di codice. I drivers di periferica, sono distinte “scatole nere” che fanno sì che un particolare pezzo di hardware risponda ad un interfaccia di programmazione ben definita. Le attività dell’utente sono effettuate tramite una serie di chiamate standardizzate indipendenti dal driver specifico. Quindi i driver possono essere costruiti separatamente dal resto del kernel e “inseriti” a runtime quando necessario.
1. Seminario di approfondimento Sistemi Operativi A.A. 2014/2015
LINUX DEVICE DRIVERS
Raffaela D’Aniello - 0124000637
Luisa Barbarino - 0124000484
Daniele Ioviero – 0124000459
Fabio Nisci - 0124000074
2. Introduzione
Uno dei molti vantaggi del Sistema Operativo
Linux è che il suo “interno” è aperto a tutti. Il
kernel Linux è un corpo grande e complesso di
codice. I drivers di periferica, sono distinte
“scatole nere” che fanno sì che un particolare
pezzo di hardware risponda ad un interfaccia di
programmazione ben definita. Le attività
dell’utente sono effettuate tramite una serie di
chiamate standardizzate indipendenti dal driver
specifico. Quindi i driver possono essere costruiti
separatamente dal resto del kernel e "inseriti" a
runtime quando necessario.
3. Ruolo dei dispositivi periferici
Forniscono il meccanismo (quali funzionalità devono
essere forniti), non la politica (come possono essere
utilizzate quelle capacità).
Esempio: la gestione Unix del display grafico è diviso tra il
server X, che conosce l'hardware e offre un'interfaccia
unificata per programmi utente, e il gestori di finestre e
di sessione, che implementano una particolare politica
senza sapere nulla sull'hardware. Gli utenti possono
utilizzare lo stesso gestore di finestre su hardware diversi,
e viceversa, diversi utenti possono eseguire diverse
configurazioni sulla stessa workstation.
Il driver di periferica è uno strato di software che si trova
tra le applicazioni e il dispositivo vero e proprio.
4. Caratteristiche di driver di periferica
supportano sia il funzionamento sincrono e
asincrono.
hanno la capacità di essere aperti più volte.
capacità di sfruttare tutte le funzionalità
dell'hardware.
semplice (è la mancanza di strati di software a
"semplificare le cose" o fornire le operazioni
legate alla politica.)
6. Classi di dispositivi e moduli
Character devices:
- lettura come un flusso di byte (come un file).
- accesso per mezzo di nodi del file system.
I dispositivi a blocchi:
- trasferimento di dati in blocchi.
- esempio: disco.
Le interfacce di rete:
- scambia dati sulla rete.
- Un driver di rete non sa nulla di singole connessioni, gestisce solo
i pacchetti.
USB:
il dispositivo stesso si presenta nel sistema come un dispositivo char (una
porta seriale USB, per esempio), un dispositivo a blocchi (un lettore di
schede di memoria USB), o un dispositivo di rete (un'interfaccia Ethernet
USB).
7. Costruzione ed esecuzione di moduli
Il driver di periferica è progettato, caricato,
scaricato come modulo del kernel.
Sviluppo:
- sorgente del kernel.
- compilazioni.
- controllare la distribuzione Linux.
9. Modulo Kernel VS Applicazione utente
Un modulo kernel deve essere inizializzato e terminato
adeguatamente.
Non esiste la funzione printf, ma printk.
Bisogna includere i file header di Linux. (es. <include/linux>)
Bugs nel driver di dispositivo possono causare il crash del kernel.
Un modulo kernel si esegue in area kernel.
Nei moduli kernel c’è una maggiore concorrenza:
- Interrupt e ISR
- Timer
- Supporto SMP
Per cui un driver di dispositivo deve:
- Essere rientrante, gestire la concorrenza ed evitare race condition.
10. Polling VS Interrupt
Polling
- Attesa attiva.
- Consuma cicli di CPU.
- Adatto a I/O con velocità molta.
Interrupt
- Asincrono.
- Serve in base al flusso dei dati.
- Adatto a I/O a velocità lenta.
11. Gestore delle Interrupt
ISR:
- Effettua delle operazioni quando avviene un interrupt dal dispositivo.
- Il carico di lavoro dipende dal dispositivo.
Restrizioni:
- È eseguito in area kernel quindi non può trasferire dati da/allo spazio
utente
- Non può far addormentare i processi, non può usare system call come
wait_event, bloccare un semaforo/scheduler.
Il ruolo:
- Dà feedback al dispositivo sulla recezione di un interrupt.
- Scrive/legge dati.
- Pulisce l’interrupt bit (flag).
- Sveglia processi addormentati sul dispositivo o che aspettano un evento.
12. I/O Bloccante
Cosa succeed se un driver non può soddisfare immediatamente
una richiesta?
- Lettura quando non vi sono dati.
- Scrittura quando il dispositivo non è pronto a ricevere dati.
Il processo chiamante non si cura di tale problema:
- Il programmatore semplicemente invoca read() e write().
- Ci si aspetta che tali funzioni ritornino dopo aver effettuato
le operazioni designate.
Il driver dovrebbe:
- “bloccare” il processo
- Metterlo a dormire fino a quando non si può procedure con
la richiesta
14. Sleeping
Cosa vuol dire quando un processo “dorme”?
- Contrassegnato come essere in uno stato speciale.
- Rimosso dalla coda di esecuzione dello scheduler.
- Non verrà eseguito finchè non accade qualche evento nel
prossimo futuro.
Regole dello sleeping:
- Mai dormire quando ci si trova in un contesto atomico (in
possesso di un blocco, gli interrupt disabilitati, ecc)
- Non può assumere lo stato del sistema dopo il risveglio (es.
la risorsa potrebbe non essere disponibile)
- Assicurarsi alcuni altri processi possono svegliarsi
15. Wait Queue
È una struttura del kernel
- Un elenco di tutti i processi in attesa di uno specifico
evento
- Rendere possibile per il vostro processo di sonno da
trovare
Gestito da “wait queue head”:
- Wait_queue_head_t è definita in <linux / wait.h>
- Può essere definita e inizializzata staticamente con
DECLARE_WAIT_QUEUE_HEAD (nome);
- O dinamicamente: wait_queue_head_t nome_coda e
init_waitqueue_head (& nome_coda);
16. System Call Select/ Poll
La chiamata di sistema select / poll:
- Consente all'applicazione utente di attendere la ricezione
di dati su uno o più descrittori di file.
- Chiamata f_ops-> poll metodo di tutti i descrittori di file.
- Ogni poll-> metodo deve restituire se i dati sono disponibili
o meno.
- Se nessun descrittore di file ha i dati disponibili, la
chiamata poll / select deve attendere i dati su tali
descrittori di file.
- Si deve sapere tutto sulle code di attesa che potrebbero
essere utilizzati per segnalare nuovi dati
18. Costruiamo un driver
Il driver che costruiremo nelle prossime slides appartiene alla
classe dei character devices.
Il dispositivo implementa la lettura/scrittura di un carattere.
Questo dispositivo, anche non essendo molto utile ai fini
pratici, fornisce un valido esempio sul funzionamento
completo di un driver.
È semplice da implementare, in quanto non si interfaccia a
nessun dispositivo hardware reale (oltre che al computer
stesso).
21. Grazie per l’attenzione
Credits:
Linux Device Drivers, Third Edition
di Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman
Linux Device Drivers Lectures
di Yan Luo