下圖說明 I/O 管理員如何為使用直接 I/O 的 DMA 傳輸作業設定 IRP_MJ_READ 要求。
上圖說明驅動程式如何使用 IRP 的 MdlAddress 來傳輸讀取要求的數據。 此圖中的驅動程式使用封包式系統或總線主控DMA,並將裝置物件的Flags與DO_DIRECT_IO進行邏輯或運算。
某些範圍的使用者空間虛擬位址代表目前線程的緩衝區,而該緩衝區的內容實際上可能會儲存在一些實際不和諧的頁面上(上圖中的深色底紋)。 I/O 管理員會建立 MDL 來描述此緩衝區。 MDL 是記憶體管理員所定義的不透明數據結構,會將特定虛擬位址範圍對應至一或多個以頁面為基礎的實體地址範圍。 如需詳細資訊,請參閱使用 MDL 。
I/O 管理員會服務目前線程的讀取要求,其中線程會傳遞代表緩衝區的使用者空間虛擬位址範圍。
I/O 管理員或文件系統驅動程式(FSD)會檢查使用者提供的緩衝區的可存取性,並使用先前建立的 MDL 呼叫 MmProbeAndLockPages。 MmProbeAndLockPages 也會填入 MDL 中對應的實體地址範圍。
如上圖所示,虛擬範圍的 MDL 可以有數個對應的頁面型實體地址專案,而緩衝區的虛擬範圍可能會從 MDL 所描述的第一頁和最後一頁開始到最後一頁的某個字節位移開始和結束。
I/O 管理員會在要求傳輸作業的 IRP 中,提供 MDL (MdlAddress) 的指標。 在驅動程式完成 IRP 之後,I/O 管理員或文件系統呼叫 MmUnlockPages 之前,MDL 中所述的實體頁面會保持鎖定狀態並指派給緩衝區。 不過,即使在 IRP 傳送到設備驅動器或可能分層於裝置驅動程式的任何中繼驅動程式之前,這類 MDL 中的虛擬位址仍可能會變成看不見(且無效)。
如果驅動程式使用以封包為基礎的系統或總線主機 DMA,其 AdapterControl 例程會使用 IRP 的 MdlAddress 指標呼叫 MmGetMdlVirtualAddress,以取得 MDL 頁面型專案的基底虛擬位址。
接著,AdapterControl 例程會使用 MmGetMdlVirtualAddress 傳回的基地址呼叫 MapTransfer,以直接從裝置讀取數據到物理記憶體。 (如需詳細資訊,請參閱 配接器物件和 DMA。)
驅動程序應該一律檢查緩衝區長度。 請注意,I/O 管理員不會為長度為零的緩衝區建立 MDL。