Nota
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare ad accedere o a cambiare directory.
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare a cambiare directory.
Alcuni driver in modalità kernel, ad esempio i driver seriali e paralleli, non devono essere residenti in memoria, a meno che i dispositivi gestiti non siano aperti. Tuttavia, purché sia presente una connessione o una porta attiva, parte del codice driver che gestisce tale porta deve essere residente per il servizio del dispositivo. Quando la porta o la connessione non viene usata, il codice del driver non è obbligatorio. Al contrario, un driver per un disco che contiene codice di sistema, codice dell'applicazione o il file di paging del sistema deve essere sempre residente in memoria perché il driver trasferisce costantemente i dati tra il dispositivo e il sistema.
Un driver per un dispositivo usato sporadicamente (ad esempio un modem) può liberare spazio di sistema quando il dispositivo gestito non è attivo. Se si inserisce in una singola sezione il codice che deve essere residente per il servizio di un dispositivo attivo e se il driver blocca il codice in memoria durante l'uso del dispositivo, è possibile designare questa sezione come pageable. Quando il dispositivo del driver viene aperto, il sistema operativo porta la sezione paginabile in memoria e il driver la blocca fino a quando non è più necessaria.
Il codice del driver audio cd di sistema usa questa tecnica. Il codice per il driver viene raggruppato in sezioni visualizzabili in base al produttore del dispositivo CD. Alcuni marchi potrebbero non essere mai presenti in un determinato sistema. Inoltre, anche se un CD-ROM esiste in un sistema, è possibile accedervi raramente, quindi il raggruppamento di codice in sezioni visualizzabili in base al tipo CD assicura che il codice per i dispositivi che non esistono in un computer specifico non venga mai caricato. Tuttavia, quando si accede al dispositivo, il sistema carica il codice per il dispositivo CD appropriato. Then the driver calls the MmLockPagableCodeSection routine, as described later in this article, to lock its code into memory while its device is being used.
Per isolare il codice di paging in una sezione denominata, contrassegnarlo con la direttiva del compilatore seguente:
#pragma alloc_text(PAGE*Xxx***, *RoutineName***)
The name of a pageable code section must start with the four letters "PAGE" and can be followed by up to four characters (represented here as Xxx) to uniquely identify the section. Le prime quattro lettere del nome della sezione (ovvero "PAGE") devono essere maiuscole. The RoutineName identifies an entry point to be included in the pageable section.
Il nome più breve valido per una sezione di codice pageable in un file driver è semplicemente PAGE. Ad esempio, la direttiva pragma nell'esempio di codice seguente identifica RdrCreateConnection come punto di ingresso in una sezione di codice paginabile denominata PAGE.
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, RdrCreateConnection)
#endif
MmLockPagableCodeSection locks in the whole contents of the section that contains the routine referenced in the call. In other words, this call makes every routine associated with the same PAGEXxx identifier resident and locked in memory. In other words, this call makes every routine associated with the same PAGEXxx identifier resident and locked in memory.
MmLockPagableCodeSection returns a handle to be used when unlocking the section (by calling the MmUnlockPagableImageSection routine) or when the driver must lock the section from additional locations in its code.
Un driver può anche trattare i dati usati raramente come visualizzabili in modo che anche esso possa essere eseguito il paging fino a quando il dispositivo supportato non è attivo. Ad esempio, il driver mixer di sistema usa dati paginabili. Al dispositivo mixer non è associato alcun I/O asincrono, quindi questo driver può rendere i dati visualizzabili.
Il nome di una sezione di dati di paging deve iniziare con le quattro lettere "PAGE" e può essere seguito da un massimo di quattro caratteri per identificare in modo univoco la sezione. Le prime quattro lettere del nome della sezione (ovvero "PAGE") devono essere maiuscole.
Evitare di assegnare nomi identici alle sezioni di codice e dati. Per rendere il codice sorgente più leggibile, gli sviluppatori di driver in genere assegnano il nome PAGE alla sezione del codice pageable perché questo nome è breve e potrebbe apparire in numerose direttive pragma alloc_text. I nomi più lunghi vengono quindi assegnati a qualsiasi sezione di dati paginabile ,ad esempio PAGEDATA per data_seg, PAGEBSS per bss_seg e così via, che il driver potrebbe richiedere.
Ad esempio, le prime due direttive pragma nell'esempio di codice seguente definiscono due sezioni di dati paginabili, PAGEDATA e PAGEBSS. PAGEDATA viene dichiarato usando la direttiva pragma data_seg e contiene dati inizializzati. PAGEBSS viene dichiarato usando la direttiva pragma bss_seg e contiene dati non inizializzati.
#pragma data_seg("PAGEDATA")
#pragma bss_seg("PAGEBSS")
INT Variable1 = 1;
INT Variable2;
CHAR Array1[64*1024] = { 0 };
CHAR Array2[64*1024];
#pragma data_seg()
#pragma bss_seg()
In questo esempio di codice, Variable1 e Array1 sono inizializzati esplicitamente e sono quindi inseriti nella sezione PAGEDATA.
Variable2 e Array2 vengono inizializzati a zero in modo implicito e inseriti nella sezione PAGEBSS.
L'inizializzazione implicita delle variabili globali su zero riduce le dimensioni del file eseguibile su disco ed è preferibile rispetto all'inizializzazione esplicita a zero. È consigliabile evitare l'inizializzazione zero esplicita, tranne nei casi in cui è necessario per inserire una variabile in una sezione di dati specifica.
To make a data section memory-resident and lock it in memory, a driver calls MmLockPagableDataSection, passing a data item that appears in the pageable data section. MmLockPagableDataSection returns a handle to be used in subsequent locking or unlocking requests.
To restore a locked section's pageable status, call MmUnlockPagableImageSection, passing the handle value returned by MmLockPagableCodeSection or MmLockPagableDataSection, as appropriate. A driver's Unload routine must call MmUnlockPagableImageSection to release each handle it obtains for lockable code and data sections.
Il blocco di una sezione è un'operazione costosa perché il gestore della memoria deve cercare il relativo elenco di moduli caricati prima di bloccare le pagine in memoria. If a driver locks a section from many locations in its code, it should use the more efficient MmLockPagableSectionByHandle after its initial call to MmLockPagableXxxSection.
The handle passed to MmLockPagableSectionByHandle is the handle returned by the earlier call to MmLockPagableCodeSection or MmLockPagableDataSection.
The memory manager maintains a count for each section handle and increments this count every time that a driver calls MmLockPagableXxx for that section. A call to MmUnlockPagableImageSection decrements the count. Finché il contatore di qualsiasi handle di sezione è diverso da zero, quella sezione rimane vincolata in memoria.
L'handle di una sezione è valido purché venga caricato il driver. Therefore, a driver should call MmLockPagableXxxSection only one time. If the driver requires more locking calls, it should use MmLockPagableSectionByHandle.
Se la sezione viene sottoposta a paging quando viene chiamata la routine di blocco, il gestore della memoria richiama la sezione e imposta il conteggio dei riferimenti a uno. If the section is paged out when the lock routine is called, the memory manager pages in the section and sets its reference count to one.
L'uso di questa tecnica riduce al minimo l'effetto del driver sulle risorse di sistema. Quando il driver viene eseguito, può bloccare in memoria il codice e i dati che devono essere residenti. Quando non sono presenti richieste di I/O in sospeso per il dispositivo, ovvero quando il dispositivo viene chiuso o se il dispositivo non è mai stato aperto, il driver può sbloccare lo stesso codice o gli stessi dati, rendendoli disponibili per il paging.
Tuttavia, dopo che un driver collega gli interrupt, qualunque codice del driver che può essere chiamato durante il processo di gestione degli interrupt deve risiedere sempre in memoria. Anche se alcuni driver di dispositivo possono essere resi visualizzabili o bloccati in memoria su richiesta, alcuni core set di codice e dati di un driver di questo tipo devono essere residenti in modo permanente nello spazio di sistema.
Prendere in considerazione le linee guida di implementazione seguenti per bloccare un codice o una sezione di dati.
The primary use of the Mm(Un)LockXxx routines is to enable normally nonpaged code or data to be made pageable and brought in as nonpaged code or data. I driver come il driver seriale e il driver parallelo sono esempi validi: se non sono presenti handle aperti per un dispositivo gestito da un driver di questo tipo, le parti del codice non sono necessarie e possono rimanere aperte. Il redirector e il server sono anche esempi validi di driver che possono usare questa tecnica. Quando non sono presenti connessioni attive, è possibile eseguire il paging di entrambi i componenti.
L'intera sezione paginabile è bloccata in memoria.
Una sezione per il codice e una per i dati per ciascun driver è efficiente. Molte sezioni denominate, divisibili in pagine, sono generalmente inefficienti.
Mantieni separate le sezioni esclusivamente paginabili e quelle paginabili ma bloccabili su richiesta.
Queste routine possono causare attività di I/O pesanti quando il gestore della memoria carica la sezione. If a driver must lock a section from several locations in its code, it should use MmLockPagableSectionByHandle. If a driver must lock a section from several locations in its code, it should use MmLockPagableSectionByHandle.