在我的过程的上下文中,我可以获得该块的VIRTUAL内存地址,
但是我需要找出它的PHYSICAL内存地址才能将其传递给一些外部设备。
1.在用户模式下,有没有办法将虚拟地址翻译成我的程序中的物理地址?
2.如果没有,我可以在KERNEL模式下找到这个虚拟到物理映射。我想这意味着我必须写一个司机去做…?你知道我可以使用的任何随时可用的驱动程序/ DLL / API,我的应用程序(程序)将与其进行翻译?
如果我必须自己写驱动程序,我该怎么做这个翻译?我使用哪些功能?它是mmGetPhysicalAddress()吗?如何使用它?
另外,如果我理解正确,mmGetPhysicalAddress()返回虚拟基地址在调用进程上下文中的物理地址。但是,如果调用进程是驱动程序,并且我正在使用我的应用程序来调用该函数的驱动程序,我正在改变上下文,并且当mmGetPhysicalAddress例程被调用时,我已经不再在应用程序的上下文中…所以如何在应用程序(用户模式)内存空间中翻译虚拟地址,而不是驱动程序?
任何答案,提示和代码摘录将非常感谢!
谢谢
不,你不能确保它保持锁定。如果您的进程崩溃或者提前退出怎么办?如果用户杀死它呢?该内存将被重用于其他内容,如果您的设备仍在执行DMA操作,则最终会导致数据丢失/损坏或错误检查(BSOD)。
此外,MapUserPhysicalPages是Windows AWE(地址窗口扩展)的一部分,用于在32位版本的Windows Server上处理超过4 GB的RAM。我不认为这是用来攻击用户模式的DMA。
1.在用户模式下,有没有办法将虚拟地址翻译成我的程序中的物理地址?
有些驱动程序可以让您执行此操作,但是您无法在Windows上对用户模式进行DMA编程,并且还具有稳定且安全的系统。使作为有限用户帐户运行的进程读/写物理内存允许该进程拥有系统。如果这是用于一次性系统或原型,这可能是可以接受的,但如果您期望其他人(特别是付费客户)使用您的软件和设备,则应该编写一个驱动程序。
2.如果没有,我可以在KERNEL模式下找到这个虚拟到物理映射。我想这意味着我必须写一个司机去做…?
这是解决这个问题的推荐方法。
你知道我可以使用的任何随时可用的驱动程序/ DLL / API,我的应用程序(程序)将与其进行翻译?
您可以使用MDL (Memory Descriptor List)锁定任意内存,包括用户模式进程所拥有的内存缓冲区,并将其虚拟地址转换为物理地址。您还可以让Windows临时为通过使用METHOD_IN_DIRECT
或METHOD_OUT_DIRECT
调用DeviceIoControl的缓冲区创建一个MDL。
请注意,虚拟地址空间中的连续页面在物理地址空间中几乎不会连续。希望您的设备旨在处理这一点。
如果我必须自己写驱动程序,我该怎么做这个翻译?我使用哪些功能?它是mmGetPhysicalAddress()吗?如何使用它?
写一个驱动程序还有更多的只是调用几个API。如果你要写一个驱动程序,我会推荐从MSDN和OSR读取尽可能多的相关材料。另外,看看Windows Driver Kit中的例子。
另外,如果我理解正确,mmGetPhysicalAddress()返回虚拟基地址在调用进程上下文中的物理地址。但是,如果调用进程是驱动程序,并且我正在使用我的应用程序来调用该函数的驱动程序,我正在改变上下文,并且当mmGetPhysicalAddress例程被调用时,我已经不再在应用程序的上下文中…所以如何在应用程序(用户模式)内存空间中翻译虚拟地址,而不是驱动程序?
驱动程序不是进程。驱动程序可以在任何进程的上下文以及各种提升的上下文(中断处理程序和DPC)中运行。
相关文章
转载注明原文:c++ 如何将虚拟内存地址翻译成物理地址? - 代码日志