24 Jun 2023, 12:49 PM
24 Jun 2023, 12:49 PM

14. Sistema di I/O

Il sistema di I/O è l’insieme dei metodi per controllare i dispositivi di I/O con l’obiettivo di fornire ai processi utente un’interfaccia efficiente e indipendente dai dispositivi. Consiste nell’interazione tra l’hardware di I/O e il software di I/O, determinato dal sistema operativo.

Hardware di I/O

Esistono numerosi ed eterogenei dispositivi di I/O che si differenziano tra loro per le funzioni che svolgono, come la memorizzazione (dischi, nastri), la trasmissione (modem, schede di rete) e l'interazione uomo-macchina (tastiera, monitor). Tuttavia, tutti i dispositivi di I/O condividono alcuni componenti fondamentali, tra cui:

Controllore dei dispositivi

Il controllore è la parte elettronica di un dispositivo, detto anche device controller. Viene connesso tramite bus al resto del sistema. È associato ad un indirizzo e contiene registri per comandare il dispositivo:

L’accesso ai registri può avvenire in vari modi:

Per esempio per il display l’hardware mappa i registri e la memoria del display nello spazio di indirizzi
fisico, si scrive nella memoria (frame buffer) i cambi che avvengono nello schermo e le descrizioni grafiche nell’area della coda di comandi. Scrivere nel registro comando potrebbe causare all’hardware grafico del display di fare qualcosa.

Accesso ai dispositivi di I/O

Esistono inoltre differenti tecniche con le quali la CPU ed il controllore comunicano. Vediamone alcune.

Polling

Lo stato del dispositivo viene determinato mediante la lettura ripetuta del busy-bit del registro di status: quando è 0 il comando viene scritto nel registro di controllo, il command-ready-bit viene posto a 1 e l’operazione di I/O viene eseguita. Questa è chiaramente un tecnica di busy waiting e causa uno spreco delle risorse e del tempo di CPU, specialmente se si cerca di comunicare con periferiche molto lente.

Interrupt

Il dispositivo di I/O avverte la CPU tramite un segnale su una connessione fisica. Gli interrupt sono una problematica complessa, per questo sono gestiti da un apposito controllore di interrupt. Questo perchè:

DMA - Direct Memory Access

Questa tecnica è basata sull'idea di scaricare l'onere della gestione dell'I/O da parte della CPU, su un controllore dedicato chiamato DMA controller. In questo modo non sprechiamo la CPU per controllare il registro di stato del controllore e trasferire pochi byte alla volta. Ma come opera il DMA controller?
Una volta ottenuti tutti gli indirizzi necessari dalla CPU (l’indirizzo di partenza dei blocchi/memoria da trasferire, l’indirizzo di destinazione, il numero di byte da trasferire e la direzione del trasferimento), il DMA controller interagisce direttamente con il controller della periferica, mentre la CPU effettua altre operazioni. Al termine dell'operazione, notifica la CPU con un interrupt.

Interfaccia di I/O

I dispositivi di I/O si differenziano per molti aspetti e pertanto si rende necessaria dell’astrazione, incapsulamento e software layering per nascondere le differenze al kernel del sistema operativo, costruendo un’interfaccia comune che dà un insieme di funzioni standard. Le differenze sono incapsulate nei device driver. Le interfacce semplificano il lavoro del sistema operativo aggiungendo nuovo hardware senza modificare il sistema operativo.

Dispositivi a blocco e a carattere

L’interfaccia dei dispositivi a blocchi è utilizzata dai dispositivi che memorizzano e trasferiscono dati in blocchi, la lettura e scrittura di un blocco è indipendente dagli altri, i comandi sono di read, write e seek, ed è tipica nei dischi.

L’interfaccia dei dispositivi a carattere è utilizzata dai dispositivi che memorizzano e trasferiscono stringhe di caratteri anzichè blocchi di dati. Non esiste indirizzamento (seek) e i comandi tipici utilizzati sono get e put. I dispositivi tipici sono terminali, mouse e porte seriali.

Software di I/O

Gli obiettivi del software di I/O sono l’indipendenza dal dispositivo, la notazione uniforme, la gestione degli errori, la gestione di varie opzioni di trasferimento e le prestazioni.
È organizzato per livelli di astrazione:

  1. Gestori degli interrupt: sono astratti il più possibile dal resto del sistema operativo e bloccano/sbloccano i processi attraverso semafori o segnali.
  2. Device driver: devono tradurre le richieste astratte del livello superiore in richieste device dependent, contengono tutto il codice device-dependent, condivisi per classi di dispositivi, interagiscono con i controllori dei dispositivi e tipicamente scritti in linguaggio macchina.
  3. Software del sistema operativo indipendente dal dispositivo: ha funzioni speciali come la definizione di interfacce comuni, naming (individuare un dispositivo e gestire i nomi), protezione (tutte le primitive di I/O sono privilegiate) e buffering, ovvero la memorizzazione dei dati durante un trasferimento per gestire diverse velocità e diverse dimensioni. Deve definire la dimensione del blocco, allocare e rilasciare i dispositivi e gestire gli errori tipicamente device-dependent.
  4. Programmi utente: tipicamente system call per l’accesso ai dispositivi

Per esempio nello spooling durante la gestione di I/O dedicato più processi possono voler scrivere su una stampante contemporaneamente, ma le stampe non devono essere interfogliate, pertanto i dati da processare vanno accodati nella spooling directory e lo spooler, un processo di sistema è l’unico autorizzato ad accedere alla stampante. Periodicamente stampa i dati nella spooling directory.