tags:

views:

148

answers:

3

Under Linux, C++, and GCC, can I get a physical address for a given virtual address? I know I won't be able to manipulate the physical address as a physical address.

+5  A: 

Nope. There's no guarantee that a virtual address is based off a physical address (it may be a mapped file with no representation in RAM, for instance.) As well, the OS is free to move virtual addresses around in physical memory at any time, so there's no guarantee that a physical address will remain correct or valid.

Why do you think you need a physical address? What are you trying to accomplish?

Jonathan Grynspan
yes, i know it could swapped to disk or be moved around. i merely want to observe the PAs
Ross Rogers
*Why* do you want to do that, though? There may be a solution to whatever problem you face that can be implemented safely and/or portably, but until we know what specific problem you're dealing with, we can't offer any suggestions.
Jonathan Grynspan
I want to check if the os is continuing to share the page between two processes after a fork which would indicate that one of the processes is writing to the page after the fork. Writing to the page is something I don't expect.
Ross Rogers
You could mprotect() that page and remove PROT_WRITE. If you crash, something's writing to the page ...
nos
Now that you know what you're trying to accomplish, you might want to open a new question (or edit this one) to ask "How can I tell if a page remains shared between two processes after fork?"
R..
It's very possible that the physical address will not change between processes until the first time one writes to the page. This is called *copy-on-write* semantics and is an extremely common feature of modern systems. I'd go as far as to say that every UNIX-like OS currently in use does it.
Jonathan Grynspan
+2  A: 

I am sure you could write a linux kernel module that would tell you how your address spaces is mapped. That would be fun

Or look at /proc/pid/maps

I am looking at http://www.amazon.com/Linux-Kernel-Development-Robert-Love/dp/0672325128

pm100
+1  A: 

There is not good way to do this without your code running within the kernel, though you might be able to do it if your program is running at root and you are able to read /proc/kcore (and maybe /proc/kallsyms) and through a lot of work are able to locate the page table info for your process and look up the address in there.

The problem with this is that while you are doing this your program is not going to stay put. Even if the page containing the address is never paged out it could be moved (on x86 some pages aren't able to be used for DMA, so a page may be moved just to set up an IO operation, and I'm sure that there are other reasons that a page could be moved without being swapped out).

Additionally, while you are reading the page tables they are changing. You can't lock them from application space the way you can in kernel space, so I'm not sure you can ever take a good snap shot of this structure.

If you really want to watch page addresses change as programs execute your best bet is to implement a kernel module that lets you query them or just read the entire page mapping each time your called read on a special device file. I don't think that this would be too difficult since the current process's process control block is available in calls to a driver's read function. It would get trickier if you were to want to be able examine other processes's mappings as well.

nategoose