Uso dell'I/O memorizzato nel buffer

Un driver che servizi un dispositivo interattivo o lento, o che in genere trasferisce quantità relativamente piccole di dati alla volta, deve usare il metodo di trasferimento di I/O memorizzato nel buffer . L'uso di operazioni di I/O memorizzate nel buffer per trasferimenti interattivi di piccole dimensioni migliora l'utilizzo complessivo della memoria fisica, perché il gestore della memoria non deve bloccare una pagina fisica completa per ogni trasferimento, perché per i driver che richiedono operazioni di I/O dirette. In genere, video, tastiera, mouse, seriale e driver paralleli richiedono I/O memorizzati nel buffer.

Il gestore di I/O determina che un'operazione di I/O usa l'I/O memorizzato nel buffer come indicato di seguito:

La figura seguente illustra come il gestore di I/O configura una richiesta di IRP_MJ_READ per un'operazione di trasferimento che usa operazioni di I/O memorizzate nel buffer.

diagramma che illustra un i/o memorizzato nel buffer memorizzato nel buffer degli utenti.

La figura mostra una panoramica del modo in cui i driver possono usare il puntatore SystemBuffer in IRP per trasferire i dati per una richiesta di lettura, quando un driver ha ORed i flag dell'oggetto dispositivo con DO_BUFFERED_IO:

  1. Alcuni indirizzi virtuali dello spazio utente rappresentano il buffer del thread corrente e il contenuto del buffer potrebbe essere archiviato in un intervallo di indirizzi fisici basati su pagina (ombreggiatura scura nella figura precedente).

  2. Il gestore di I/O esegue la richiesta di lettura del thread corrente, per cui il thread passa un intervallo di indirizzi virtuali dello spazio utente che rappresentano un buffer.

  3. Il gestore di I/O controlla il buffer fornito dall'utente per l'accessibilità e chiama ExAllocatePoolWithTag per creare un buffer dello spazio di sistema non di paging (SystemBuffer) le dimensioni del buffer fornito dall'utente.

  4. Il gestore di I/O fornisce l'accesso al SystemBuffer appena allocato nell'IRP che invia al driver.

    Se la figura mostra una richiesta di scrittura, il gestore di I/O copia i dati dal buffer utente nel buffer di sistema prima dell'invio dell'IRP al driver.

  5. Per la richiesta di lettura illustrata nella figura precedente, il driver legge i dati dal dispositivo nel buffer dello spazio di sistema. La memoria per questo buffer non è in pagine e il driver può accedere in modo sicuro al buffer senza prima bloccarlo. Quando la richiesta di lettura è stata soddisfatta, il driver chiama IoCompleteRequest con IRP.

  6. Quando il thread originale è nuovamente attivo, il gestore di I/O copia i dati di lettura dal buffer di sistema nel buffer utente. Chiama anche ExFreePool per rilasciare il buffer di sistema.

Dopo che il gestore di I/O ha creato un buffer dello spazio di sistema per il driver, il thread in modalità utente richiedente può essere scambiato e la relativa memoria fisica può essere riutilizzata da un altro thread, possibilmente da un thread appartenente a un altro processo. Tuttavia, l'intervallo di indirizzi virtuali dello spazio di sistema fornito nell'IRP rimane valido fino a quando il driver chiama IoCompleteRequest con IRP.

I driver che trasferiscono grandi quantità di dati alla volta, in particolare i driver che eseguono trasferimenti a più pagine, non devono tentare di usare operazioni di I/O memorizzate nel buffer. Durante l'esecuzione del sistema, il pool non di paging può diventare frammentato in modo che il gestore di I/O non possa allocare buffer di spazio di sistema contigui di grandi dimensioni per l'invio in irP per un driver di questo tipo.

In genere, un driver usa operazioni di I/O memorizzate nel buffer per alcuni tipi di runtime di integrazione, ad esempio IRP_MJ_DEVICE_CONTROL richieste, anche se usa anche operazioni di I/O dirette. I driver che usano operazioni di I/O dirette in genere lo fanno solo per le richieste di IRP_MJ_READ e IRP_MJ_WRITE e possibilmente richieste di IRP_MJ_INTERNAL_DEVICE_CONTROL definite dal driver che richiedono trasferimenti di dati di grandi dimensioni.

Ogni IRP_MJ_DEVICE_CONTROL e IRP_MJ_INTERNAL_DEVICE_CONTROL richiesta include un codice di controllo di I/O. Se il codice di controllo di I/O indica che l'IRP deve essere supportato tramite I/O memorizzato nel buffer, il gestore di I/O usa un singolo buffer di sistema per rappresentare i buffer di input e output dell'applicazione utente. Un driver che supporta tale codice di controllo di I/O deve leggere i dati di input (se presenti) dal buffer e quindi fornire i dati di output (se presenti) sovrascrivendo i dati di input. Per altre informazioni, vedere Definizione dei codici di controllo di I/O.