MDL相关总结

MDL的本质就是记录一段虚拟地址所对应着的一系列的物理地址。

MDL数据结构的结尾是一组PFN,记录着物理地址,相关宏是MmGetMdlPfnArray。

初始化:一般用用IoAllocateMdl初始化,但是这个步骤并没有建立起虚拟地址和物理地址的联系。IoAllocateMdl会调用MmInitializeMdl用于初始化MDL,填充MDL的header。

校验MDL对应的虚拟地址可读写:MmProbeAndLockPages

建立与PFN的联系:MmBuildMdlForNonPagedPool,IoBuildPartialMdl,MmProbeAndLockPages

建立新的虚拟地址映射:MmMapLockedPages,MmMapLockedPagesSpecifyCache,MmGetSystemAddressForMdl,MmGetSystemAddressForMdlSafe

非分页:MDL_SOURCE_IS_NONPAGED_POOL

 

在驱动中使用MDL的四种可能:

1. 在驱动中如果使用METHOD_NEITHER方法,传进来的buffer就是user app的buffer。如果需要在任意进程上下文中使用这个buffer,需要创建MDL,并且判断MDL对应的内存是否可以操作,最后把它重新map到kernel mode memory。WRK中的ExLockUserBuffer是个很好的例子。其实METHOD_IN_DIRECT方式也是这个原理,只不过是OS帮你去做这些事情了。

2. 在A驱动中发起向B驱动的请求。最好的例子是磁盘类驱动ClassSendSrbSynchronous。首先创建IRP,并且创建irp->MdlAddress

3. 将大的数据量大的IRP,拆分成IRP。典型的例子是BulkUSB中的BulkUsb_DispatchReadWrite。首先创建IRP,然后创建一个MDL,紧接着调用IoBuildPartialMdl(借用Irp->MdlAddress)修改这个MDL。这个MDL作为参数传到底层驱动(或者其他驱动),其实主要操作是更新PFN数组。

4. 分配物理内存。但物理内存不一定连续。使用MmAllocatePagesForMdl分配MDL,然后用MmMapLockedPagesSpecifyCache将这段内存map到新的地址。

微软比较全的文档:http://msdn.microsoft.com/en-us/windows/hardware/gg487427.aspx

posted @ 2011-12-13 17:45  Fan Zhang  阅读(875)  评论(0编辑  收藏  举报