I am trying to find the physical addresses of heap variables, stack variables and memory mapped peripheral addresses using the /proc/{pid}/pagemap file using the steps detailed in the file: http://lxr.free-electrons.com/source/Documentation/vm/pagemap.txt. The procedure detailed works well for stack and heap variables. However, for memory mapped peripherals no page is found in the /proc/{pid}/pagemap file. The output of 'cat /proc/{pid}/maps' is:

00008000-0000a000 r-xp 00000000 b3:02 289852     /home/linaro/ocm_test/write-memory
00011000-00012000 r--p 00001000 b3:02 289852     /home/linaro/ocm_test/write-memory
00012000-00013000 rw-p 00002000 b3:02 289852     /home/linaro/ocm_test/write-memory
00013000-00034000 rw-p 00000000 00:00 0          [heap]
b2efe000-b6dfe000 rw-s 00001000 b3:02 284849     /dev/uio0
b6dfe000-b6ed2000 r-xp 00000000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6ed2000-b6eda000 ---p 000d4000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6eda000-b6edc000 r--p 000d4000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6edc000-b6edd000 rw-p 000d6000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6edd000-b6ee0000 rw-p 00000000 00:00 0 
b6ee0000-b6ee2000 r-xp 00000000 b3:02 27519      /usr/lib/libinterface.so
b6ee2000-b6ee9000 ---p 00002000 b3:02 27519      /usr/lib/libinterface.so
b6ee9000-b6eea000 r--p 00001000 b3:02 27519      /usr/lib/libinterface.so
b6eea000-b6eeb000 rw-p 00002000 b3:02 27519      /usr/lib/libinterface.so
b6efb000-b6f12000 r-xp 00000000 b3:02 282407     /lib/arm-linux-gnueabihf/ld-2.15.so
b6f13000-b6f14000 rw-p 00000000 00:00 0 
b6f14000-b6f15000 rw-s 00000000 b3:02 284849     /dev/uio0
b6f15000-b6f19000 rw-p 00000000 00:00 0 
b6f19000-b6f1a000 r--p 00016000 b3:02 282407     /lib/arm-linux-gnueabihf/ld-2.15.so
b6f1a000-b6f1b000 rw-p 00017000 b3:02 282407     /lib/arm-linux-gnueabihf/ld-2.15.so
bee36000-bee57000 rw-p 00000000 00:00 0          [stack]
bef1f000-bef20000 r-xp 00000000 00:00 0          [sigpage]
ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]

When I try to find the physical addresses of 0x00013000 or 0xbee36000 it works fine. However the page map file returns no page found when I try to find the physical address corresponding to 0xb2efe000 which belongs to /dev/uio0. I am trying to do this for verification purposes. I know a physical address exists because I have used mmap on 0x1b90000 ignored to find 0xb2efe000. Could someone please explain why the /proc/{pid}/pagemap file doesn't contain the physical address?

1 Answer 1


Short answer: The pagemap interface exposes information stored in the struct page associated with the address. I/O addresses are raw pfn mappings without an associated struct page and therefore are exposed as zeroes.

Longer answer Remapping physical addresses (including I/O addresses) to userspace is done by calling remap_pfn_range. These remapped addresses do not have a struct page associated with them (they're raw pfn mappings). To remember that these addresses are special, this function sets VM_PFNMAP on the vma.

The pagemap interface exposes a bunch of fields that have to do with what's in the struct page associated with the address. But there is no such struct for these addresses. So pagemap just skips them:

When pagemap is used, the kernel does a page walk using walk_page_range. vmas tagged with VM_PFNMAP are treated differently:

 * vma(VM_PFNMAP) doesn't have any valid struct pages behind VM_PFNMAP
 * range, so we don't walk over it as we do for normal vmas. However,
 * Some callers are interested in handling hole range and they don't
 * want to just ignore any single address range. Such users certainly
 * define their ->pte_hole() callbacks, so let's delegate them to handle
 * vma(VM_PFNMAP).

pagemap's pte_hole just puts a bunch of zero entries (modulo some additional flag for VM_SOFTDIRTY). That's why you don't see it...

I don't know of any kernel interface that allows you to retrieve the physical address for such mappings. But it would be easy to do with a kernel module or using crash.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .