Skip to content

davidhcefx/Translate-Virtual-Address-To-Physical-Address-in-Linux-Kernel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 

Repository files navigation

Translate Virtual Address To Physical Address

The followings are some ways to translate a virtual address to the corresponding physical address, if exist.

Step 1. Walk the page tables to get pte_t *.

// struct mm_struct *mm : The memory descriptor of the current process.
// unsigned long address: The virtual address to be translated.
pgd_t *pgd = pgd_offset(mm, address);
if (!pgd_none(*pgd) && !pgd_bad(*pgd)) {
    pud_t *pud = pud_offset(pgd, address);
    if (!pud_none(*pud) && !pud_bad(*pud)) {
        pmd_t *pmd = pmd_offset(pud, address);
        if (!pmd_none(*pmd) && !pmd_bad(*pmd)) {
            pte_t *pte = pte_offset_map(pmd, address);
            if (!pte_none(*pte)) {
                // now you get a pointer pointing to a pte entry!
            }
            pte_unmap(pte);
        }
    }
}       

Step 2.

  • A) Calculate the bits directly.
// Assume it is on 32-bit machine with 4 KB pages.
unsigned long phys = pte_val(*pte) & 0xfffff000 + address & 0x00000fff;
  • B) With the help of a page descriptor.
struct page *pg = pte_page(*pte);
unsigned long phys = page_to_phys(pg);

Userspace:

cat /proc/<pid>/maps to get virtual address intervals.

xxd /proc/<pid>/pagemap to get virtual - physical address mappings. documention

Others:

  • virt_to_page(unsigned long address) seems to be a faster way to get struct page*, but you have to make sure the return value is valid. (code)

  • virt_to_phys(volatile void *address) is only suitable for addresses directly mapped or mapped by kmalloc. (code)

Reference:

  • Understanding the Linux Kernel 3rd (Daniel P. Bovet, Marco Cesati), Sections 2.5, 8.1, 9.2, etc.
  • page_to_phys from <asm/io.h>
  • How to get the physical address from the logical one in a Linux kernel module? Stack Overflow
  • How to find the physical address of a variable from user-space in Linux? Stack Overflow

About

Translate Virtual Address To Physical Address in Linux Kernel

Topics

Resources

Stars

Watchers

Forks