Is there any API for determining the physical address from virtual address in Linux operating system?
相关问题
- What uses more memory in c++? An 2 ints or 2 funct
- Is shmid returned by shmget() unique across proces
- how to get running process information in java?
- Achieving the equivalent of a variable-length (loc
- Memory for python.exe on Windows 7 python 32 - Num
Because user land memory's physical address is unknown.
Linux uses demand paging for user land memory. Your user land object will not have physical memory until it is accessed. When the system is short of memory, your user land object may be swapped out and lose physical memory unless the page is locked for the process. When you access the object again, it is swapped in and given physical memory, but it is likely different physical memory from the previous one. You may take a snapshot of page mapping, but it is not guaranteed to be the same in the next moment.
So, looking for the physical address of a user land object is usually meaningless.
Kernel and user space work with virtual addresses (also called linear addresses) that are mapped to physical addresses by the memory management hardware. This mapping is defined by page tables, set up by the operating system.
DMA devices use bus addresses. On an i386 PC, bus addresses are the same as physical addresses, but other architectures may have special address mapping hardware to convert bus addresses to physical addresses.
In Linux, you can use these functions from
asm/io.h
:All this is about accessing ordinary memory. There is also "shared memory" on the PCI or ISA bus. It can be mapped inside a 32-bit address space using ioremap(), and then used via the readb(), writeb() (etc.) functions.
Life is complicated by the fact that there are various caches around, so that different ways to access the same physical address need not give the same result.
Also, the real physical address behind virtual address can change. Even more than that - there could be no address associated with a virtual address until you access that memory.
As for the user-land API, there are none that I am aware of.
As answered before, normal programs should not need to worry about physical addresses as they run in a virtual address space with all its conveniences. Furthermore, not every virtual address has a physical address, the may belong to mapped files or swapped pages. However, sometimes it may be interesting to see this mapping, even in userland.
For this purpose, the Linux kernel exposes its mapping to userland through a set of files in the
/proc
. The documentation can be found here. Short summary:/proc/$pid/maps
provides a list of mappings of virtual addresses together with additional information, such as the corresponding file for mapped files./proc/$pid/pagemap
provides more information about each mapped page, including the physical address if it exists.This website provides a C program that dumps the mappings of all running processes using this interface and an explanation of what it does.
/proc/<pid>/pagemap
userland minimal runnable examplevirt_to_phys_user.c:
GitHub upstream.
Usage:
sudo
is required to read/proc/<pid>/pagemap
even if you have file permissions as explained at: https://unix.stackexchange.com/questions/345915/how-to-change-permission-of-proc-self-pagemap-file/383838#383838As mentioned at: https://stackoverflow.com/a/46247716/895245 Linux allocates page tables lazily, so make sure that you read and write a byte to that address from the test program before using
virt_to_phys_user
.How to test it out
Test program:
The test program outputs the address of a variable it owns, and its PID, e.g.:
and then you can pass convert the virtual address with:
Finally, the conversion can be tested by using
/dev/mem
to observe / modify the memory, but you can't do this on Ubuntu 17.04 without recompiling the kernel as it requires:CONFIG_STRICT_DEVMEM=n
, see also: How to access physical addresses from user space in Linux? Buildroot is an easy way to overcome that however.Alternatively, you can use a Virtual machine like QEMU monitor's
xp
command: How to decode /proc/pid/pagemap entries in Linux?See this to dump all pages: How to decode /proc/pid/pagemap entries in Linux?
Userland subset of this question: How to find the physical address of a variable from user-space in Linux?
Dump all process pages with
/proc/<pid>/maps
/proc/<pid>/maps
lists all the addresses ranges of the process, so we can walk that to translate all pages: /proc/[pid]/pagemaps and /proc/[pid]/maps | linuxKerneland
virt_to_phys
only works forkmalloc
addressesFrom a kernel module,
virt_to_phys
, has been mentioned.However, it is import to highlight that it has this limitation.
E.g. it fails for module variables.
arc/x86/include/asm/io.h
documentation:Here is a kernel module that illustrates that together with an userland test.
So this is not a very general possibility. See: How to get the physical address from the logical one in a Linux kernel module? for kernel module methods exclusively.
The suggested C program above usually works, but it can return misleading results in (at least) two ways:
Bottom line is, to ensure a more reliable result: for read-only mappings, read from every page at least once before querying its PFN. For write-enabled pages, write into every page at least once before querying its PFN.
Of course, theoretically, even after obtaining a "stable" PFN, the mappings could always change arbitrarily at runtime (for example when moving pages into and out of swap) and should not be relied upon.