Linux (Ubuntu), C language: Virtual to Physical Address Translation

Tommy picture Tommy · Jun 5, 2011 · Viewed 9.7k times · Source

As the title suggests, I have a problem of obtaining the physical address from a virtual one.

Let me explain: Given a variable declaration in process space, how can I derive it's physical address mapped by the OS?

I've stumbled upon some sys calls /asm/io.h where the virt_to_phys() function is defined; however it seems this header is outdated and I can't find a work around.

However; io.h is available at: /usr/src/linux-headers-2.6.35-28-generic/arch/x86/include/asm/. My current kernel is 2.6.35-28, but io.h isn't included in /usr/include/asm/?

So, to reiterate: I need a way to get the physical address from virtual. Preferably derived from within the application at runtime. But even a workaround of using a monitor of /proc/PID/maps will do.

Any ideas or comments would be greatly appreciated.


EDIT After doing a bit of research on this topic I found something that helps in this regard.

It turns out this is more than doable, although requires a bit of a workaround. Here is a link to a simple app that analyses the current mapped pages. The file in question turns out is (a binary file) /proc/pid/pagemap (contains the physical mapping of virtual pages). Anyway, the code in that link can be modified to serve as a monitor app or something.

I needed the physical address for cache simulation purposes.

Thanks for all the help and answers!

Answer

In user code, you can't know the physical address corresponding to a virtual address. This is information is simply not exported outside the kernel. It could even change at any time, especially if the kernel decides to swap out part of your process's memory.

In /proc/$pid/maps, you have information about what the virtual addresses in your program's address space correspond to (mmapped files, heap, stack, etc.). That's all you'll get.

If you're working on kernel code (which you aren't, apparently), you can find out the physical address corresponding to a page of memory. But even then virt_to_phys isn't the whole story; I recommend reading Linux Device Drivers (especially chapters 8 and 15).

The header asm/io.h is a kernel header. It's not available when you're compiling user code because its contents just wouldn't make sense. The functions it declares aren't available in any library, only in the kernel.