Controller

Per poter trasferire dati con un dispositivo, il sistema operativo dovrà comunicare con il controller inviandogli comandi e leggendo il suo stato, operazioni descritte all'interno del driver.

Per comunicare con la CPU, il controller possiede dei registri:

  • Command, per inviare comandi
  • Status, per leggere lo stato del dispositivo
  • Data Write, per inviare i dati
  • Data Read, per leggere i dati

che vengono utilizzati attraverso load e store su indirizzi virtuali, se la CPU usa Memory Mapped I/O, oppure attraverso istruzioni speciali se l'ISA lo supporta.

Polling

In questo metodo, il processore controlla periodicamente il registro di stato per capire se ci sono dati da trasferire, e nel caso li scrive in RAM per utilizzi futuri.

Diventa vantaggioso in caso di trasferimenti ad intervalli prevedibili, anche perchè il costo per la lettura del registro di stato è noto. Rimane comunque costoso occupare la CPU nel trasferimento di dati in RAM.

Interrupt-driven

Questa alternativa al polling sfrutta gli interrupt per notificare il processore in caso di nuovi dati disponibili.

In questo caso è vantaggioso nel caso di rari trasferimenti ad intervalli imprevedibili, perchè altrimenti la CPU continuerebbe a saltare tra il processo e l'interrupt handler.

Direct Memory Access

I metodi precedenti spendono la maggior parte del tempo per trasferire i dati sulla RAM. Questo può essere risolto delegando il compito ad hardware dedicato, cioè il Direct Memory Access, salvando tempo CPU.

L'unico incarico della CPU sarà specificare la quantità dei dati e gli indirizzi coinvolti al DMA, per poi ricevere un interrupt quando il trasferimento è completato.

Dato che la comunicazione con la RAM è diretta, il DMA non usa il sistema di traduzione della CPU, e quindi:

  • la scrittura in RAM non aggiornerebbe la cache, mentre la lettura da RAM potrebbe essere obsoleta se un write-back è in sospeso.

    Per risolvere il problema le alternative sono:

    • Passare l'I/O del DMA attraverso la cache, sprecando però spazio e invalidando dati utili alla CPU
    • Far invalidare al SO il dato su cache per richieste I/O in lettura (i.e. scrittura su RAM) e forzare un write-back per richieste in scrittura (i.e. lettura da RAM).
    • Modificare l'hardware per invalidare dei blocchi della cache
  • gli indirizzi virtuali comporterebbero l'uso della page table (in RAM) e la TLB che avrebbe gli stessi problemi della cache, mentre gli indirizzi fisici limiterebbero i dati trasferiti alla dimensione di una pagina perchè la memoria virtuale non è contigua nella memoria fisica.

    Questi problemi possono essere risolti:

    • incaricando il SO di fornire tabelle per la traduzione degli indirizzi virtuali
    • frammentando il trasferimento in sotto-trasferimenti grandi quanto le pagine

    forzando quindi il SO a collaborare per trasferimenti più grandi.