如何将虚拟内存地址转换为物理地址? [英] How to translate a virtual memory address to a physical address?

查看:134
本文介绍了如何将虚拟内存地址转换为物理地址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的C ++程序(在Windows上),我分配一块内存,并确保它在物理内存中保持锁定(未重叠和连续)(即使用VirtualAllocEx(),MapUserPhysicalPages()等)。



在我的进程的上下文中,我可以得到该块的VIRTUAL内存地址,
但我需要找出PHYSICAL内存地址的,以便将其传递到某些外部设备。





1。有什么方法可以将虚拟地址翻译成我的程序中的物理地址,用户模式?


2。如果没有,我只能在KERNEL模式下找到这个虚拟到物理映射。我想这意味着我要写一个驱动程序来做...?你知道任何现成的驱动程序/ DLL / API,我可以使用,我的应用程序(程序)将与接口做翻译?


3。如果我必须自己写驱动程序,我该如何进行翻译?我使用哪些功能?是 mmGetPhysicalAddress()吗?我如何使用它?


4。此外,如果我理解正确,mmGetPhysicalAddress()返回在调用进程上下文中的虚拟基地址的物理地址。但是如果调用进程是驱动程序,并且我使用我的应用程序调用该函数的驱动程序,我改变上下文,当我调用mmGetPhysicalAddress例程时,我不再在应用程序的上下文中...如何翻译应用程序(用户模式)内存空间中的虚拟地址,而不是驱动程序?



任何答案,提示和代码摘录将非常感谢!



感谢

解决方案

Windows),我分配一块内存,并且可以确保它在物理内存中保持锁定(不重叠和连续)(即使用VirtualAllocEx(),MapUserPhysicalPages()等)。



不,你不能真正确保它保持锁定。如果您的进程崩溃或提前退出会怎么样?如果用户杀了它怎么办?该内存将被重用于其他内容,如果您的设备仍在进行DMA,则最终会导致数据丢失/损坏或错误检查(BSOD)。



MapUserPhysicalPages 是Windows AWE(地址窗口扩展)的一部分,用于在32位版本的Windows Server上处理超过4 GB的RAM。我不认为这是用来攻击用户模式的DMA。



1。有什么方法可以把我的程序中的虚拟地址翻译成物理的,在USER模式?



有一些驱动程序,但是你不能在Windows上从用户模式编程DMA,并且仍然有一个稳定和安全的系统。使作为受限用户帐户读/写物理内存运行的进程允许该进程拥有系统。如果这是一个一次性系统或原型,这可能是可以接受的,但如果你希望其他人(特别是付费客户)使用你的软件和你的设备,你应该写一个驱动程序。



2。如果不是,我可以找到这个虚拟到物理映射只有在KERNEL模式。我想这意味着我必须写一个驱动程序来做...?



这是解决这个问题的推荐方法。



你知道我可以使用的任何现成的驱动程序/ DLL / API,我的应用程序(程序)将与之进行交互吗? / p>

您可以使用 MDL(内存描述符列表) 锁定任意内存,包括用户模式进程拥有的内存缓冲区,并将其虚拟地址转换为物理地址。您还可以让Windows临时为传递到 DeviceIoControl 的调用的缓冲区创建MDL,方法是使用 METHOD_IN_DIRECT METHOD_OUT_DIRECT



请注意,虚拟地址空间中的连续页面在物理地址空间中几乎不会连续。希望您的设备可以处理这个问题。



3。如果我自己写驱动程序,我该怎么做这个翻译?我使用哪些功能?是mmGetPhysicalAddress()吗?如何使用它?



编写驱动程序不仅仅是调用几个API还有很多。如果你要写一个驱动程序,我建议阅读尽可能多的相关资料,你可以从 MSDN OSR 。此外,请查看 Windows驱动程序工具包中的示例。



4。另外,如果我理解正确,mmGetPhysicalAddress()返回在调用进程的上下文中的虚拟基地址的物理地址。但是如果调用进程是驱动程序,并且我正在使用我的应用程序调用该函数的驱动程序,我改变上下文,我不再在应用程序的上下文中,当调用mmGetPhysicalAddress例程时...如何转换应用程序(用户模式)内存空间中的虚拟地址,而不是驱动程序?



驱动程序不是进程。驱动程序可以在任何进程的上下文中运行,以及各种高级上下文(中断处理程序和DPC)。


In my C++ program (on Windows), I'm allocating a block of memory and can make sure it stays locked (unswapped and contiguous) in physical memory (i.e. using VirtualAllocEx(), MapUserPhysicalPages() etc).

In the context of my process, I can get the VIRTUAL memory address of that block, but I need to find out the PHYSICAL memory address of it in order to pass it to some external device.


1. Is there any way I can translate the virtual address to the physical one within my program, in USER mode?

2. If not, I can find out this virtual to physical mapping only in KERNEL mode. I guess it means I have to write a driver to do it...? Do you know of any readily available driver/DLL/API which I can use, that my application (program) will interface with to do the translation?

3. In case I'll have to write the driver myself, how do I do this translation? which functions do I use? Is it mmGetPhysicalAddress()? How do I use it?

4. Also, if I understand correctly, mmGetPhysicalAddress() returns the physical address of a virtual base address that is in the context of the calling process. But if the calling process is the driver, and I'm using my application to call the driver for that function, I'm changing contexts and I am no longer in the context of the app when the mmGetPhysicalAddress routine is called... so how do I translate the virtual address in the application (user-mode) memory space, not the driver?

Any answers, tips and code excerpts will be much appreciated!!

Thanks

解决方案

In my C++ program (on Windows), I'm allocating a block of memory and can make sure it stays locked (unswapped and contiguous) in physical memory (i.e. using VirtualAllocEx(), MapUserPhysicalPages() etc).

No, you can't really ensure that it stays locked. What if your process crashes, or exits early? What if the user kills it? That memory will be reused for something else, and if your device is still doing DMA, that will eventually result in data loss/corruption or a bugcheck (BSOD).

Also, MapUserPhysicalPages is part of Windows AWE (Address Windowing Extensions), which is for handling more than 4 GB of RAM on 32-bit versions of Windows Server. I don't think it was intended to be used to hack up user-mode DMA.

1. Is there any way I can translate the virtual address to the physical one within my program, in USER mode?

There are drivers that let you do this, but you cannot program DMA from user mode on Windows and still have a stable and secure system. Letting a process that runs as a limited user account read/write physical memory allows that process to own the system. If this is for a one-off system or a prototype, this is probably acceptable, but if you expect other people (particularly paying customers) to use your software and your device, you should write a driver.

2. If not, I can find out this virtual to physical mapping only in KERNEL mode. I guess it means I have to write a driver to do it...?

That is the recommended way to approach this problem.

Do you know of any readily available driver/DLL/API which I can use, that my application (program) will interface with to do the translation?

You can use an MDL (Memory Descriptor List) to lock down arbitrary memory, including memory buffers owned by a user-mode process, and translate its virtual addresses into physical addresses. You can also have Windows temporarily create an MDL for the buffer passed into a call to DeviceIoControl by using METHOD_IN_DIRECT or METHOD_OUT_DIRECT.

Note that contiguous pages in the virtual address space are almost never contiguous in the physical address space. Hopefully your device is designed to handle that.

3. In case I'll have to write the driver myself, how do I do this translation? which functions do I use? Is it mmGetPhysicalAddress()? How do I use it?

There's a lot more to writing a driver than just calling a few APIs. If you're going to write a driver, I would recommend reading as much relevant material as you can from MSDN and OSR. Also, look at the examples in the Windows Driver Kit.

4. Also, if I understand correctly, mmGetPhysicalAddress() returns the physical address of a virtual base address that is in the context of the calling process. But if the calling process is the driver, and I'm using my application to call the driver for that function, I'm changing contexts and I am no longer in the context of the app when the mmGetPhysicalAddress routine is called... so how do I translate the virtual address in the application (user-mode) memory space, not the driver?

Drivers are not processes. A driver can run in the context of any process, as well as various elevated contexts (interrupt handlers and DPCs).

这篇关于如何将虚拟内存地址转换为物理地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆