Is there any API for determining the physical address from virtual address in Linux?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5748492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:46:56  来源:igfitidea点击:

Is there any API for determining the physical address from virtual address in Linux?

linuxmemorymemory-managementlinux-kernelvirtual-address-space

提问by Karthik Balaguru

Is there any API for determining the physical address from virtual address in Linux operating system?

Is there any API for determining the physical address from virtual address in Linux operating system?

回答by Karthik Balaguru

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.

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.

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:

In Linux, you can use these functions from asm/io.h:

  • virt_to_phys(virt_addr);
  • phys_to_virt(phys_addr);
  • virt_to_bus(virt_addr);
  • bus_to_virt(bus_addr);
  • virt_to_phys(virt_addr);
  • phys_to_virt(phys_addr);
  • virt_to_bus(virt_addr);
  • bus_to_virt(bus_addr);

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.

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.

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.

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 for the user-land API, there are none that I am aware of.

回答by ingomueller.net

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.

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:

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:

  1. /proc/$pid/mapsprovides a list of mappings of virtual addresses together with additional information, such as the corresponding file for mapped files.
  2. /proc/$pid/pagemapprovides more information about each mapped page, including the physical address if it exists.
  1. /proc/$pid/mapsprovides a list of mappings of virtual addresses together with additional information, such as the corresponding file for mapped files.
  2. /proc/$pid/pagemapprovides more information about each mapped page, including the physical address if it exists.

This websiteprovides a C program that dumps the mappings of all running processes using this interface and an explanation of what it does.

This websiteprovides a C program that dumps the mappings of all running processes using this interface and an explanation of what it does.

回答by hiro

I wonder why there is no user-land API.

I wonder why there is no user-land API.

Because user land memory's physical address is unknown.

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.

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.

So, looking for the physical address of a user land object is usually meaningless.

回答by Roei Schus

The suggested C program above usually works, but it can return misleading results in (at least) two ways:

The suggested C program above usually works, but it can return misleading results in (at least) two ways:

  1. The page is not present (but the virtual addressed is mapped to a page!). This happens due to lazy mapping by the OS: it maps addresses only when they are actually accessed.
  2. The returned PFN points to some possibly temporary physical page which could be changed soon after due to copy-on-write. For example: for memory mapped files, the PFN can point to the read-only copy. For anonymous mappings, the PFN of all pages in the mapping could be one specific read-only page full of 0s (from which all anonymous pages spawn when written to).
  1. The page is not present (but the virtual addressed is mapped to a page!). This happens due to lazy mapping by the OS: it maps addresses only when they are actually accessed.
  2. The returned PFN points to some possibly temporary physical page which could be changed soon after due to copy-on-write. For example: for memory mapped files, the PFN can point to the read-only copy. For anonymous mappings, the PFN of all pages in the mapping could be one specific read-only page full of 0s (from which all anonymous pages spawn when written to).

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.

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.

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.