如何将虚拟内存地址转换为物理地址? < P>在我的C++程序(在Windows上),我分配一个内存块,并确保它在物理内存(即使用ValualLoCuffE()、MaMulePrimaPrimePuthes()等)中保持锁定(未交换和连续)。
在我的进程上下文中,我可以得到该块的虚拟内存地址, 但我需要找出它的物理内存地址,以便将它传递到某个外部设备如何将虚拟内存地址转换为物理地址? < P>在我的C++程序(在Windows上),我分配一个内存块,并确保它在物理内存(即使用ValualLoCuffE()、MaMulePrimaPrimePuthes()等)中保持锁定(未交换和连续)。,c++,windows,memory,virtual-address-space,C++,Windows,Memory,Virtual Address Space,在我的进程上下文中,我可以得到该块的虚拟内存地址, 但我需要找出它的物理内存地址,以便将它传递到某个外部设备 1.在用户模式下,有没有办法将程序中的虚拟地址转换为物理地址 二,。如果没有,我只能在内核模式下找到这个虚拟到物理的映射。我猜这意味着我必须写一个驱动程序来做。。。?你知道我可以使用的任何现成的驱动程序/DLL/API,我的应用程序(程序)将与之接口来进行翻译吗? 三,。如果我必须自己写驱动程序,我该如何翻译?我应该使用哪些功能?是mmGetPhysicalAddress()吗?我如何
1.在用户模式下,有没有办法将程序中的虚拟地址转换为物理地址
二,。如果没有,我只能在内核模式下找到这个虚拟到物理的映射。我猜这意味着我必须写一个驱动程序来做。。。?你知道我可以使用的任何现成的驱动程序/DLL/API,我的应用程序(程序)将与之接口来进行翻译吗?
三,。如果我必须自己写驱动程序,我该如何翻译?我应该使用哪些功能?是mmGetPhysicalAddress()吗?我如何使用它?
四,。另外,如果我理解正确,mmGetPhysicalAddress()将返回调用进程上下文中的虚拟基址的物理地址。但是,如果调用过程是驱动程序,并且我正在使用我的应用程序调用该函数的驱动程序,那么我正在更改上下文,当调用mmGetPhysicalAddress例程时,我不再处于应用程序的上下文中。。。那么,如何在应用程序(用户模式)内存空间而不是驱动程序中转换虚拟地址呢 任何答案、提示和代码摘录都将不胜感激 谢谢1)不 2) 是的,你必须写一个驱动程序。最好是虚拟驱动程序,或者为特殊的外部设备更改驱动程序 3) 这让人很困惑
MmGetPhysicalAddress
应该是您正在寻找的方法,但我真的不知道物理地址如何映射到物理内存上的银行/芯片等
4) 您不能使用分页内存,因为它会被重新定位。您可以在MDL上使用MmProbeAndLockPages
锁定分页内存,您可以在从用户模式调用上下文传入的内存上进行构建。但最好分配非分页内存并将其交给用户模式应用程序
PVOID p = ExAllocatePoolWithTag( NonPagedPool, POOL_TAG );
PHYSICAL_ADDRESS realAddr = MmGetPhysicalAddress( p );
// use realAddr
在我的C++程序(在Windows上),我分配一个内存块,并确保它在物理内存中(如使用ValualLoCuffE()、MaMulePrimaPrimePuthes()等)保持锁定(未交换和连续)。 不,你不能保证它一直锁着。如果您的进程崩溃或提前退出怎么办?如果用户杀死它怎么办?该内存将被重新用于其他用途,如果您的设备仍在进行DMA,则最终将导致数据丢失/损坏或错误检查(BSOD)
另外,MapUserPhysicalPages
是Windows AWE(地址窗口扩展)的一部分,用于在32位版本的Windows Server上处理超过4 GB的RAM。我不认为它是用来破解用户模式DMA的
一,。在用户模式下,有没有办法将程序中的虚拟地址转换为物理地址
有一些驱动程序允许您这样做,但您无法在Windows上从用户模式对DMA进行编程,并且仍然有一个稳定和安全的系统。让作为有限用户帐户运行的进程读/写物理内存允许该进程拥有系统。如果这是一个一次性系统或原型,这可能是可以接受的,但如果你希望其他人(特别是付费客户)使用你的软件和设备,你应该编写一个驱动程序
二,。如果没有,我只能在内核模式下找到这个虚拟到物理的映射。我猜这意味着我必须写一个驱动程序来做
这是解决这个问题的推荐方法
你知道我可以使用的任何现成的驱动程序/DLL/API,我的应用程序(程序)将与之接口来进行翻译吗
您可以使用锁定任意内存,包括用户模式进程拥有的内存缓冲区,并将其虚拟地址转换为物理地址。您还可以让Windows使用或为传递到DeviceIoControl
调用中的缓冲区临时创建MDL
请注意,虚拟地址空间中的连续页在物理地址空间中几乎从不连续。希望您的设备能够处理这个问题
三,。如果我必须自己写驱动程序,我该如何翻译?我应该使用哪些功能?是mmGetPhysicalAddress()吗?我如何使用它
编写驱动程序不仅仅是调用几个API,还有很多事情要做。如果你打算写一个驱动程序,我建议你尽可能多地阅读和中的相关材料。另外,请看中的示例
四,。另外,如果我理解正确,mmGetPhysicalAddress()将返回调用进程上下文中的虚拟基址的物理地址。但是,如果调用过程是驱动程序,并且我正在使用我的应用程序调用该函数的驱动程序,那么我正在更改上下文,当调用mmGetPhysicalAddress例程时,我不再处于应用程序的上下文中。。。那么,如何在应用程序(用户模式)内存空间而不是驱动程序中转换虚拟地址呢
驱动程序不是进程。驱动程序可以在任何进程的上下文中运行,也可以在各种提升上下文(中断处理程序和DPC)中运行。你真的不应该在用户模式下做这样的事情;正如Christopher所说,您需要锁定页面,这样mm就不会在设备使用备份内存时决定对其进行分页,从而导致随机内存页面损坏 但是,如果调用进程是驱动程序,并且我正在使用我的应用程序调用该函数的驱动程序,那么我正在更改上下文,当调用mmGetPhysicalAddress例程时,我不再处于应用程序的上下文中 司机
1: kd> .formats 0xf9a10054
Binary: 11111001 10100001 00000000 01010100
Page Directory Pointer Index(PDPI) 11 Index into