使用页表演练查找物理地址

时间:2014-04-08 13:25:03

标签: linux-kernel linux-device-driver

寻找访问进程页表条目以查找作为char驱动程序读取例程的参数传递的进程数据的物理地址。这里是相同的代码 禁用PAE模式的Linux x86-32bit

    static unsigned long getDirEntry(const pgd_t *pgd, void *address)
    {
         unsigned long d_index;
         unsigned long *pgd_array = (unsigned long *)pgd;
         unsigned long tmp;

         unsigned long t = (unsigned long)address;
         d_index = t >> 22;
         tmp = pgd_array[d_index];
         tmp = tmp >> 12;
         tmp = tmp << 12;
         return tmp;
    } 

    static unsigned long getPageTableEntry(unsigned long d, void *address)
    {
         unsigned long t;
         unsigned long *pte_array = (unsigned long *)d;
         unsigned long tmp;

         t = (unsigned long)address;
         t = t << 10;
         t = t >> 22;

         tmp = pte_array[t];
         tmp = tmp >> 12;
         tmp = tmp << 12;
         return tmp;
    }

    ssize_t ptd_read(struct file *filp,char *buf, size_t count, loff_t *fpos)
    {
        unsigned long d, pte, t;
        unsigned int pfn, pfn2;
        struct page *pptr, *pptr2;

        struct mm_struct *mm = current->mm;
        pgd_t *pgd = mm->pgd;
        d = getDirEntry(pgd,buf);
        pfn = d >> 12;
        pptr = pfn_to_page(pfn);
        printk(KERN_INFO "struct page = %p\n",pptr);
        kptr1 = kmap(pptr);
        pte = getPageTableEntry((unsigned long)kptr1,buf);
        pfn2 = pte >>12;
        pptr2 = pfn_to_page(pfn2);
        kptr2 = kmap(pptr2);
        printk(KERN_INFO "KERNEL:Frame mapped to page  = %p\n",kptr2);
        t = (unsigned long)buf;
        t = t << 20;
        t = t >> 20;
        printk(KERN_INFO "Value of string inside physical page = %s\n",(char *)kptr2+t);
        return 0;
    }

此代码适用于禁用PAE的所有32位内核。代码需要更改才能在启用了PAE的内核上工作(现在大多数发行版都是默认的), 需要输入/建议将上面的模块移植到PAE启用的内核,任何帮助都非常感谢。

1 个答案:

答案 0 :(得分:0)

基本上你已经静态地完成了页面漫游,所以当启用PAE时它现在可以正常工作,因此可以使用更多的宏PAGE_SHIFT,所以请参阅下面的链接

It gives you knowledge about all this macros