带有 MmMapIoSpace 的幻数
Posted
技术标签:
【中文标题】带有 MmMapIoSpace 的幻数【英文标题】:Magic number with MmMapIoSpace 【发布时间】:2012-06-17 19:23:12 【问题描述】:因此,在使用MmMapiospace
映射内存空间时,我注意到在某个时间点之后,数据在写入时只是被丢弃了。没有抛出错误、断点甚至错误检查。一切正常,没有任何不良影响。
我决定做一个写/读测试(驱动程序会在每个字节写入 1,以达到 预期 大小的长度),读取器(用户态)模式将读取并报告 1 的位置结束了。
它得出的数字是 3208,这是一个看似不错的整数(/8=401、/256=12 等)
这是怎么回事?为什么我无法映射完整的缓冲区空间?
EDIT 而在 64 位中它下降到 2492。
【问题讨论】:
MmMapIoSpace 用于访问内存映射的 I/O 设备。内存的行为方式可能取决于所讨论的硬件设备。相反,如果您将其指向物理 RAM 而不是 I/O 设备,则您正在以不受支持的方式使用它,并且行为可能是未定义的。如果这不能回答您的问题,您需要向我们提供更多背景信息:例如,您的设备驱动程序管理的是哪种设备? 它将内存映射到用户级驱动程序 哇,我刚刚意识到我发表了一个愚蠢的评论。它将用户级内存映射到驱动程序可写缓冲区。 根据 MmMapIoSpace 的文档,我很确定它不支持您尝试执行的操作。您是想让您的驱动程序访问由用户空间进程分配的内存缓冲区,还是试图让用户空间进程访问由驱动程序分配的缓冲区? PhysicalAddress(传递给 MmMapIoSpace)是否与页面对齐?我看不到映射如何在页面末尾停止工作,所以我猜测您看到的 3208/2492 完全取决于其页面内 PhysicalAddress 的偏移量。 (页面在 x86 和 x64 系统上为 4096 字节,在 IA64 上为 8192。) 【参考方案1】:我不是专家,但我不明白如何依赖 MmMapIoSpace 来完成您的要求,因为无法保证用户空间缓冲区在物理内存中是连续的。
相反,我认为您应该使用IoAllocateMdl
和MmProbeAndLockPages
锁定用户缓冲区,然后使用MmGetSystemAddressForMdlSafe
将其映射到系统地址空间。这个进程是described here。
如前所述,我认为映射失败的点(缓冲区中的 3208/2492 字节)可能只是页面的末尾,但这很容易验证:获取用户空间应用程序报告未写入的第一个字节的(虚拟)地址而不是偏移量,并检查它是否是 4096 的倍数。
【讨论】:
是的,它是 (40400/9)。有趣的!我会玩弄你的方法,看看我是否不能做这样的事情。 不要在工作中使用扳手,但 40400 不是 4096 的倍数。(请注意,在编程模式下,Windows 计算器会在您进行除法时截断小数部分。) 成功了!工作完美!非常感谢!以上是关于带有 MmMapIoSpace 的幻数的主要内容,如果未能解决你的问题,请参考以下文章