配置System-Space記憶體
重要
本主題中所討論的 ExAllocatePool DIS 已在 Windows 10 2004 版中淘汰,且已由ExAllocatePool2和ExAllocatePool3取代。 如需詳細資訊,請參閱 更新對 ExAllocatePool2 和 ExAllocatePool3 的已淘汰 ExAllocatePool 呼叫。
驅動程式可以使用 其裝置延伸模組 內的系統組態空間作為裝置特定資訊的全域儲存區域。 驅動程式只能使用核心堆疊,將少量資料傳遞至其內部常式。 某些驅動程式必須配置額外的系統空間記憶體數量,通常適用于 I/O 緩衝區。
若要配置 I/O 緩衝區空間,要使用的最佳記憶體配置常式是 MmAllocateNonCachedMemory、 MmAllocateContiguousMemorySpecifyCache、 AllocateCommonBuffer (,如果驅動程式的裝置使用匯流排主機 DMA 或系統 DMA 控制器的自動初始化模式) 或 ExAllocatePoolWithTag。
非分頁集區通常會隨著系統執行而分散,因此驅動程式的 DriverEntry 常式應該呼叫這些常式來設定驅動程式所需的任何長期 I/O 緩衝區。 除了 ExAllocatePoolWithTag以外,每個常式都會配置在處理器特定界限上對齊的記憶體, (處理器的資料快取行大小) 來提供最佳效能。
驅動程式應該盡可能以經濟方式配置 I/O 緩衝區,因為非分頁集區記憶體是有限的系統資源。 一般而言,驅動程式應該避免重複呼叫這些支援常式,以要求配置小於PAGE_SIZE,因為每個小於PAGE_SIZE的配置也會隨附集區標頭,用於內部管理配置。
以經濟方式配置驅動程式緩衝區空間的秘訣
若要以經濟方式配置 I/O 緩衝區記憶體,請注意下列事項:
每次呼叫 MmAllocateNonCachedMemory 或 MmAllocateContiguousMemorySpecifyCache 時,一律會傳回系統頁面大小的完整倍數,不論要求配置的大小為何。 因此,小於頁面的要求會四捨五入為完整頁面,而頁面上的任何其餘位元組則會浪費;呼叫函式的驅動程式無法存取它們,而且無法供其他核心模式程式碼使用。
對 AllocateCommonBuffer的每個呼叫都會使用至少一個配接器物件對應暫存器,該暫存器至少對應一個位元組和最多一個頁面。 如需對應暫存器和使用常見緩衝區的詳細資訊,請參閱配接器 物件和 DMA。
使用 ExAllocatePoolWithTag 配置記憶體
驅動程式也可以呼叫ExAllocatePoolWithTag,為PoolType參數指定下列其中一個系統定義的POOL_TYPE值:
PoolType = 在 IRQL > APC_LEVEL執行時,驅動程式可能存取的任何物件或資源,都未儲存在裝置延伸模組或控制器擴充功能中的NonPagedPool。
針對這個 PoolType 值, ExAllocatePoolWithTag 會配置指定的 NumberOfBytes 小於或等於PAGE_SIZE時要求的記憶體數量。 否則,最後配置頁面上的任何餘數位元組會浪費:無法供呼叫端存取,其他核心模式程式碼無法使用。
例如,在 x86 上,5 KB 的配置要求 (KB) 會傳回兩個 4 KB 頁面。 第二頁的最後 3 KB 無法供呼叫端或其他呼叫端使用。 為了避免浪費非分頁集區,驅動程式應該有效率地配置多個頁面。 例如,例如,驅動程式可以進行兩個配置,一個用於PAGE_SIZE,另一個用於 1 KB,以配置總計 5 KB。
注意 從 Windows Vista 開始,系統會自動新增額外的記憶體,因此不需要兩個配置。
PoolType = 一律在 IRQL < = APC_LEVEL存取記憶體的PagedPool,而且不在檔案系統的寫入路徑中。
如果 ExAllocatePoolWithTag 無法配置要求的位元組數目,則會傳回 Null 指標。 驅動程式應該一律檢查傳回的指標。 如果其值為 Null, DriverEntry 常式 (或任何其他傳回 NTSTATUS 值的驅動程式常式,) 應該傳回STATUS_INSUFFICIENT_RESOURCES或盡可能處理錯誤狀況。