MmAllocateMdlForIoSpace 函式 (wdm.h)
MmAllocateMdlForIoSpace 例程會配置 MDL,並初始化此 MDL 來描述 I/O 位址空間中的一組實體位址範圍。
語法
NTSTATUS MmAllocateMdlForIoSpace(
[in] PMM_PHYSICAL_ADDRESS_LIST PhysicalAddressList,
[in] SIZE_T NumberOfEntries,
[out] PMDL *NewMdl
);
參數
[in] PhysicalAddressList
MM_PHYSICAL_ADDRESS_LIST 結構的陣列指標,描述要包含在配置之 MDL 中的實體地址範圍。
[in] NumberOfEntries
PhysicalAddressList 所指向之 MM_PHYSICAL_ADDRESS_LIST 陣列中的元素數目。
[out] NewMdl
例程將指標寫入新配置之 MDL 的位置指標。
傳回值
如果成功,mmAllocateMdlForIoSpace 會傳回STATUS_SUCCESS。 可能的錯誤傳回值包括下列狀態代碼。
傳回碼 | 描述 |
---|---|
STATUS_INVALID_PARAMETER_1 | 實體位址未對齊頁面界限;或實體位址範圍不是頁面大小的倍數;或實體位址範圍是由作系統用於 RAM,無法當做 I/O 空間使用。 |
STATUS_INSUFFICIENT_RESOURCES | 系統資源不足,無法執行要求的作業。 |
請勿假設上述錯誤傳回碼清單是詳盡的。 例程可能會傳回未出現在清單中的錯誤碼。
言論
此例程接受輸入參數,這是描述 I/O 位址空間中一組實體位址範圍的 MM_PHYSICAL_ADDRESS_LIST 結構陣列,並配置描述這些範圍的 MDL。 數位中連續的實體位址範圍不需要連續。
PhysicalAddressList 陣列中的實體地址範圍必須符合下列條件:
每個範圍的基底實體地址必須對齊記憶體中的PAGE_SIZE界限。
每個範圍的大小,以位元組為單位,必須是PAGE_SIZE的整數倍數。
所有實體位址範圍都必須位於記憶體中,才能當做 I/O 位址空間使用。 它們不能位於作系統用於 RAM 的記憶體空間中。
所有範圍的總大小必須小於 4 GB。 具體來說,總大小不能超過 2^32 - 1 個字節。
呼叫端負責在不再需要時釋放已配置的 MDL。 若要釋放 MDL,請呼叫 IoFreeMdl 例程。 如需 MDL 的詳細資訊,請參閱使用 MDL 。
MmAllocateMdlForIoSpace 所建立的 MDL 不會對應至虛擬記憶體,但可以提供給 mapTransferEx 等例程,以起始 MDL 所描述之實體記憶體範圍的 DMA 傳輸。 若要將此 MDL 對應至連續的虛擬位址範圍,以便處理器存取它,請呼叫 MmMapLockedPagesSpecifyCache 例程。
只有作系統未保留做為記憶體的實體位址空間範圍可供驅動程式使用,以作為 I/O 位址空間使用。 驅動程式會使用 I/O 位址空間來存取記憶體對應的硬體資源,例如裝置快取器。 當驅動程序啟動時,它可能會收到一或多個實體位址範圍作為已轉譯的硬體資源。 如需詳細資訊,請參閱 Bus-Relative 位址對應至虛擬位址。
在某些處理器架構中,例如 x86,裝置可以記憶體對應或對應至專用於裝置的特殊 I/O 位址空間中的埠位址,而且與記憶體位址空間不同。 驅動程式可以使用 MmAllocateMdlForIoSpace,只配置記憶體對應裝置的 MDL。
例子
下列程式代碼範例示範如何建構 MM_PHYSICAL_ADDRESS_LIST 結構的陣列,以描述要包含在配置 MDL 中的實體地址範圍。
extern ULONG64 BasePhysicalAddress;
extern SIZE_T ChunkSize;
extern SIZE_T Stride;
#define ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0]))
NTSTATUS Status;
PMDL Mdl;
MM_PHYSICAL_ADDRESS_LIST AddressList[3];
AddressList[0].PhysicalAddress.QuadPart = BasePhysicalAddress;
AddressList[0].NumberOfBytes = ChunkSize;
BasePhysicalAddress += Stride;
AddressList[1].PhysicalAddress.QuadPart = BasePhysicalAddress;
AddressList[1].NumberOfBytes = ChunkSize;
BasePhysicalAddress += Stride;
AddressList[2].PhysicalAddress.QuadPart = BasePhysicalAddress;
AddressList[2].NumberOfBytes = ChunkSize;
Status = MmAllocateMdlForIoSpace (AddressList, ARRAYSIZE(AddressList), &Mdl);
在此範例中,起始實體位址是由 BasePhysicalAddress
變數所指定。 每個實體位址範圍中的位元組數目是由 ChunkSize
變數所指定。 從一個實體範圍的開頭到下一個開始的位元移是由 Stride
變數所指定。
BasePhysicalAddress
必須對齊記憶體中的頁面界限,ChunkSize
和 Stride
必須是頁面大小的倍數。
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | 從 Windows 8 開始提供。 |
目標平臺 | 普遍 |
標頭 | wdm.h (包括 Wdm.h) |
連結庫 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL |