1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| #include <linux/init.h> #include <linux/module.h> #include <linux/mm.h> #include <linux/mm_types.h> #include <linux/sched.h> #include <linux/export.h> #include <linux/delay.h>
static unsigned long cr0,cr3;
static unsigned long vaddr = 0;
static void get_pgtable_macro(void) { cr0 = read_cr0(); cr3 = read_cr3_pa(); printk("cr0 = 0x%lx, cr3 = 0x%lx\n",cr0,cr3); printk("PGDIR_SHIFT = %d\n", PGDIR_SHIFT); printk("P4D_SHIFT = %d\n",P4D_SHIFT); printk("PUD_SHIFT = %d\n", PUD_SHIFT); printk("PMD_SHIFT = %d\n", PMD_SHIFT); printk("PAGE_SHIFT = %d\n", PAGE_SHIFT); printk("PTRS_PER_PGD = %d\n", PTRS_PER_PGD); printk("PTRS_PER_P4D = %d\n", PTRS_PER_P4D); printk("PTRS_PER_PUD = %d\n", PTRS_PER_PUD); printk("PTRS_PER_PMD = %d\n", PTRS_PER_PMD); printk("PTRS_PER_PTE = %d\n", PTRS_PER_PTE); printk("PAGE_MASK = 0x%lx\n", PAGE_MASK); } static unsigned long vaddr2paddr(unsigned long vaddr) { pgd_t *pgd; p4d_t *p4d; pud_t *pud; pmd_t *pmd; pte_t *pte; unsigned long paddr = 0; unsigned long page_addr = 0; unsigned long page_offset = 0; pgd = pgd_offset(current->mm, vaddr); printk("pgd_val = 0x%lx, pgd_index = %lu\n", pgd_val(*pgd),pgd_index(vaddr)); if (pgd_none(*pgd)){ printk("not mapped in pgd\n"); return -1; }
p4d = p4d_offset(pgd, vaddr); printk("p4d_val = 0x%lx, p4d_index = %lu\n", p4d_val(*p4d),p4d_index(vaddr)); if(p4d_none(*p4d)) { printk("not mapped in p4d\n"); return -1; }
pud = pud_offset(p4d, vaddr); printk("pud_val = 0x%lx, pud_index = %lu\n", pud_val(*pud),pud_index(vaddr)); if (pud_none(*pud)) { printk("not mapped in pud\n"); return -1; } pmd = pmd_offset(pud, vaddr); printk("pmd_val = 0x%lx, pmd_index = %lu\n", pmd_val(*pmd),pmd_index(vaddr)); if (pmd_none(*pmd)) { printk("not mapped in pmd\n"); return -1; } pte = pte_offset_kernel(pmd, vaddr); printk("pte_val = 0x%lx, ptd_index = %lu\n", pte_val(*pte),pte_index(vaddr));
if (pte_none(*pte)) { printk("not mapped in pte\n"); return -1; } page_addr = pte_val(*pte) & PAGE_MASK; page_offset = vaddr & ~PAGE_MASK; paddr = page_addr | page_offset; printk("page_addr = %lx, page_offset = %lx\n", page_addr, page_offset); printk("vaddr = %lx, paddr = %lx\n", vaddr, paddr); return paddr; }
static int __init v2p_init(void) { unsigned long vaddr = 0 ; printk("vaddr to paddr module is running..\n"); get_pgtable_macro(); printk("\n"); vaddr = __get_free_page(GFP_KERNEL); if (vaddr == 0) { printk("__get_free_page failed..\n"); return 0; } sprintf((char *)vaddr, "hello world from kernel"); printk("get_page_vaddr=0x%lx\n", vaddr); vaddr2paddr(vaddr); ssleep(600); return 0; } static void __exit v2p_exit(void) { printk("vaddr to paddr module is leaving..\n"); free_page(vaddr); }
module_init(v2p_init); module_exit(v2p_exit); MODULE_LICENSE("GPL");
|