#include #include #include static uintptr_t virt_to_phys_address(uintptr_t vaddr) { FILE *pagemap; uintptr_t paddr = 0; off_t offset = (vaddr / sysconf(_SC_PAGESIZE)) * sizeof(uint64_t); uint64_t e; /* https://www.kernel.org/doc/Documentation/vm/pagemap.txt */ if ((pagemap = fopen("/proc/self/pagemap", "r"))) { if (lseek(fileno(pagemap), offset, SEEK_SET) == offset) { if (fread(&e, sizeof(uint64_t), 1, pagemap)) { if (e & (1ULL << 63)) { /* page present ? */ /* pfn mask */ paddr = e & ((1ULL << 54) - 1); paddr = paddr * sysconf(_SC_PAGESIZE); /* add offset within page */ paddr |= (vaddr & (sysconf(_SC_PAGESIZE) - 1)); } else printf("%s: No page present\n", __func__); } else printf("%s: fread failed\n", __func__); } else printf("%s: lseek did not find\n", __func__); fclose(pagemap); } else printf("%s: Pagemap open failed\n", __func__); return paddr; } volatile uint32_t var=0; int main() { void* phys_addr = virt_to_phys_address(&var); printf("%p %p\n", &var, phys_addr); while( var==0 ) sleep(1); printf("done\n"); fflush(stdout); return 0; }