Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将虚拟内存地址转换为物理地址? < P>在我的C++程序(在Windows上),我分配一个内存块,并确保它在物理内存(即使用ValualLoCuffE()、MaMulePrimaPrimePuthes()等)中保持锁定(未交换和连续)。_C++_Windows_Memory_Virtual Address Space - Fatal编程技术网

如何将虚拟内存地址转换为物理地址? < 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