内核驱动中,调用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中进行。