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。 可能的錯誤傳回值包括下列狀態代碼。
傳回碼 | Description |
---|---|
STATUS_INVALID_PARAMETER_1 | 實體位址未對齊頁面界限;或實體位址範圍不是頁面大小的倍數;或實體位址範圍是由 RAM 的作業系統使用,而且無法作為 I/O 空間使用。 |
STATUS_INSUFFICIENT_RESOURCES | 系統資源不足,無法執行要求的作業。 |
請勿假設上述錯誤傳回碼清單很詳盡。 例程可能會傳回未出現在清單中的錯誤碼。
備註
此例程接受輸入參數,這是 一個MM_PHYSICAL_ADDRESS_LIST 結構的數位,這些結構描述 I/O 位址空間中的一組實體位址範圍,並配置描述這些範圍的 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 開始提供。 |
目標平台 | Universal |
標頭 | wdm.h (包含 Wdm.h) |
程式庫 | NtosKrnl.lib |
Dll | NtosKrnl.exe |
IRQL | <= DISPATCH_LEVEL |