共用方式為


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必須對齊記憶體中的頁面界限,而且ChunkSizeStride必須是頁面大小的倍數。

規格需求

需求
最低支援的用戶端 從 Windows 8 開始提供。
目標平台 Universal
標頭 wdm.h (包含 Wdm.h)
程式庫 NtosKrnl.lib
Dll NtosKrnl.exe
IRQL <= DISPATCH_LEVEL

另請參閱

IoFreeMdl

MDL

MM_PHYSICAL_ADDRESS_LIST

MapTransferEx

MmMapLockedPagesSpecifyCache