内核驱动中,调用API函数:

ExAllocatePoolWithTag ,分配内存。对应的释放内存函数: ExFreePoolWithTag

IoAllocateMdl ,给定缓冲区的起始地址和长度, IoAllocateMdl 例程分配内存描述符列表 (MDL) 足以映射缓冲区。对应的释放MDL函数: IoFreeMdl。

MmBuildMdlForNonPagedPool MmBuildMdlForNonPagedPool 例程接收指定非分页虚拟内存缓冲区的 MDL,并更新它以描述基础物理页。

MmMapLockedPagesSpecifyCache,MmMapLockedPagesSpecifyCache 例程将 MDL 描述的物理页面映射到虚拟地址,并使调用方能够指定用于创建映射的缓存属性。对应的解映射函数: MmUnmapLockedPages。

PVOID MmMapLockedPagesSpecifyCache(
[in]           PMDL                                                                          MemoryDescriptorList,
[in]           __drv_strictType(KPROCESSOR_MODE / enum _MODE,__drv_typeConst)KPROCESSOR_MODE AccessMode,
[in]           __drv_strictTypeMatch(__drv_typeCond)MEMORY_CACHING_TYPE                      CacheType,
[in, optional] PVOID                                                                         RequestedAddress,
[in]           ULONG                                                                         BugCheckOnFailure,
[in]           ULONG                                                                         Priority
);

如果 MmMapLockedPagesSpecifyCache 成功执行 ,MmMapLockedPagesSpecifyCache 返回映射页面的起始地址。参数2选择 UserMode ,映射为用户模式虚拟地址。

应用程序通过 DeviceIoControl 获得映射页面起始地址,由此完成映射。

MmMapLockedPagesSpecifyCache 应在应用程序打开设备后框架调用的EVT_WDF_DEVICE_FILE_CREATE 回调函数中调用。

注意,映射完内存,在应用程序还没有退出时热插拔设备的情况下,内存的回收应在应用程序关闭对应的回调函数file close中进行。

Windows 驱动 跑在核心态(Kernel mode), 驱动 的调用者跑在 用户 态。如何使 用户 态进程与核心态 驱动 共享 内存 呢 我们知道32位 Windows 中,默认状态下虚拟空间有4G,前2G是每个进程私有的,也就是说在进程切换的时候会变化,后2G是操作系统的,所以是固定的。既然 用户 态进程和核心态 驱动 在同一个进程空间里,是不是只要直接传个 内存 地址过来,就可以访问了?理论上可以但实际上不行,因为用 (a)通过kernel命令行参数预留一些 内存 这种方法,适合于需要大块的物理连续的 内存 。 假设物理 内存 总量为256M。命令行参数中,指定 mem=224M。即只让 内核 使用前224M 内存 ,忽略其余的 内存 。 这样,我们就有了32M的 内存 可用, 内存 起始物理地址为224*1024*1024。 在 内核 态,通过ioremap,就可以将此物理地址处 IoAllocateMdl  IoAllocateMdl 函数分配足够 映射 一块缓存的MDL,给定缓存的起始地址和长度. PMDL IoAllocateMdl(     __in_opt PVOID VirtualAddress,     __in ULONG Length,     __in BOOLEAN SecondaryBuffer,     __in BOOLEAN ChargeQuota,     __inout_opt PIRP Irp OPTIONAL 在上一篇博文中我们通过使用附加进程的方式得到了该进程的PEB结构信息,本篇文章同样需要使用进程附加功能,但这次我们将实现一个更加有趣的功能,在某些情况下应用层与 内核 层需要共享一片 内存 区域通过这片区域可打通 内核 与应用层的隔离,此类功能的实现依附于MDL 内存 映射 机制实现。 I/O多数是异步的(如DPC),在执行I/O的过程中 用户 模式 线程在不断切换,所以处理I/O时访问的虚拟地址已不是原先发出I/O请求的线程的地址,那样将发生错误。创建MDL将原先位于 用户 空间的缓冲区内容 映射 到系统空间,由于 用户 模式 内存 是切换的而系统 模式 内存 对所有进程都是不变的,故不会发生以上问题。 MDL只能在 内核 态使用,但它指定的虚拟 内存 即可以是 内核 态地址也可以是 用户 态地址。如果是 用户 态的地址你必须要自行弄清地址所在的进程上下文,因为不同的进程拥有不同的地址空间,即使地址的值一模一样它们包含的数据也一定完全不同。如果是 内核 态的地址那么事情会变的稍微简单点,因为在 内核 态地址空间是共享的,同一 首先查阅CSDN,在其中有这样的定义: 内存 描述符列表 (MDL) 是一个系统定义的结构,通过一系列物理地址描述缓冲区。执行直接 I/O 的 驱动 程序从 I/O 管理器接收一个 MDL 的指针,并通过 MDL 读写数据。一些 驱动 程序在执行直接 I/O 来满足设备 I/O 控制请求时也使用 MDL。 MDL分为两部分:固定长部分和变长部分,固定长部分结构如下: Next:MDL可以连接成...