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

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:

  • 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.

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.

Leave a Comment