MDL 数据结构

《Windows驱动开发技术详解》中说
在使用直接方式来读写设备的时候,操作系统会将用户模式下的缓冲区锁住,然后操作系统将这段缓冲区在内核模式地址再次映射一遍。这样,用户模式的缓冲区和内核模式的缓冲区都使用的是同一块物理内存,无论操作系统如果切换进程,内核模式的地址都保持不变。
操作系统先将用户模式的地址锁定后会使用MDL来记录这片内存。被记录的内存在物理内存上可能是离散的,但是在虚拟内存上一定是连续的。
其实说白了,MDL就是用来建立一块虚拟地址空间与物理页面之间的映射。
MDL结构被定义在wdm.h中。。。
typedef __struct_bcount (Size ) struct _MDL {
    struct _MDL *Next ;
    CSHORT Size ;
    CSHORT MdlFlags ;
    struct _EPROCESS *Process ;
    PVOID MappedSystemVa ;
    PVOID StartVa ;
    ULONG ByteCount ;
    ULONG ByteOffset ;
} MDL , *PMDL ;

结合MSDN来理解一下每一个成员:
struct _MDL *Next;
指向MDL链表中的下一个MDL结构。
CSHORT Size;
首先要知道,一个MDL里不只有结构里的这些数据,这些只是MDL的一个头部,在头部之后储存着这个MDL所对应的各种物理页面的编号,由于一个物理页面一定是4KB对齐的,所以这个编号相当于一个物理页面起始地址的高20位,这里Size的大小就是用于存放物理页面编号与MDL头部的总大小。
CSHORT MdlFlags;
这里指令了一些与当前MDL相关的标志。
struct _EPROCESS *Process;
如果虚拟地址是某一进程的用户地址空间,那么MDL代表的这块虚拟地址必须是从属于某一个进程,这个成员指向从属进程的结构。
PVOID MappedSystemVa;
该MDL结构对应的物理页面可能被映射到内核地址空间,这个成员代表这个内核地址空间下的虚拟地址。
PVOID StartVa;
虚拟地址空间的第一个物理页的地址。
ULONG ByteCount;
虚拟地址块的大小,字节数。
ULONG ByteOffset;
表示虚拟内存首地址相对于第一个物理页的偏移。


你可能感兴趣的:(MDL 数据结构)