由pte虚地址 跟踪mmu映射流程


static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
                 struct mm_walk *walk)
{
    struct vm_area_struct *vma = walk->vma;
    struct pagemapread *pm = walk->private;
    spinlock_t *ptl;
    pte_t *pte, *orig_pte;
    int err = 0;
    unsigned long pgd;
    pmd_t pmd,pmd1,pmd2;
    unsigned long *data;


    //unsigned long pgd,pmd,pmd1;
    
    //pmd_t *pmdp;
    struct task_struct *task;
    task = current;
    if( !strcmp(task->comm, "mytest") ){
        //debug_en_highmem = 0x01;
    }else{
        //debug_en_highmem = 0x00; 
    }

        


#ifdef CONFIG_TRANSPARENT_HUGEPAGE
    error!!!
    ptl = pmd_trans_huge_lock(pmdp, vma);
    if (ptl) {
        u64 flags = 0, frame = 0;
        pmd_t pmd = *pmdp;

        if ((vma->vm_flags & VM_SOFTDIRTY) || pmd_soft_dirty(pmd))
            flags |= PM_SOFT_DIRTY;

        /*
         * Currently pmd for thp is always present because thp
         * can not be swapped-out, migrated, or HWPOISONed
         * (split in such cases instead.)
         * This if-check is just to prepare for future implementation.
         */
        if (pmd_present(pmd)) {
            struct page *page = pmd_page(pmd);

            if (page_mapcount(page) == 1)
                flags |= PM_MMAP_EXCLUSIVE;

            flags |= PM_PRESENT;
            if (pm->show_pfn)
                frame = pmd_pfn(pmd) +
                    ((addr & ~PMD_MASK) >> PAGE_SHIFT);
        }

        for (; addr != end; addr += PAGE_SIZE) {
            pagemap_entry_t pme = make_pme(frame, flags);

            err = add_to_pagemap(addr, &pme, pm);
            if (err)
                break;
            if (pm->show_pfn && (flags & PM_PRESENT))
                frame++;
        }
        spin_unlock(ptl);
        return err;
    }

    if (pmd_trans_unstable(pmdp))
        return 0;
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */

    /*
     * We can assume that @vma always points to a valid one and @end never
     * goes beyond vma->vm_end.
     */
    orig_pte = pte = pte_offset_map_lock(walk->mm, pmdp, addr, &ptl);


    //pte_t *__pte = pte_offset_map(pmd, address);    
    //(__pte_map(pmd) + pte_index(addr))
    //(pte_t *)kmap_atomic(pmd_page(*(pmd)))   //使用高端内存映射  +  pte_index(addr)
    //pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
    //__pfn_to_page(pfn)    (mem_map + ((pfn) - ARCH_PFN_OFFSET))
    


    printk("\n pagemap_pmd_range addr1 = %lx\n", addr);
    printk("pmdp = %lx\n", pmdp);
    printk("*pmdp = %lx\n", *pmdp);


    
    

    printk("mem_map = %lx\n", mem_map);
    printk( "end = %lx\n", end );

    
    //do_translation_fault

    for (; addr < end; pte++, addr += PAGE_SIZE) {
        pagemap_entry_t pme;
        printk("pte = %lx\n", pte);
        printk("*pte = %lx\n", *pte);

//此处打印 pte的地址 与 值 

//下面用另外一种办法获取到pte的值 *pte, 最终2者的结果要一样


        pgd = (unsigned long)pte >> 21;
        printk("pgd.0 = %lx\n", pgd);
        print_hex_dump_bytes("walk.datax1: ", DUMP_PREFIX_ADDRESS, (u8 *)(task->mm->pgd + pgd), 0x40 );        
        printk("pgd.1 = %lx\n", task->mm->pgd + pgd);    
        pmd = *(unsigned long *)(task->mm->pgd + pgd);
        printk("pmd.00 = %lx\n", pmd);
        //由全局页表描述符 加地址最高的11位 获取2级页表的基地址  
        //每一个表项管2M 占用8字节地址
    
    
    pmd  = pmd & 0xfffff000;
    pmd1 = pmd + 0x80000000;
    if( pmd1 >= 0xc0000000 && pmd1 <= 0xeb800000 ){
        //属于低端内存区 内核已经全部做好了映射关系 可直接访问
        //pmd1 = pmd1 | ( ((pmd>>12)&0x001ff) << 2 );  
        //print_hex_dump_bytes("walk.datax223: ", DUMP_PREFIX_ADDRESS, (u8 *)((pmd1)), 0x1000 ); 
    }

    pmd2 = pmd1 +  ((((unsigned long)pte)>>12) & 0x1ff)*4;
    //二级页表内指定页的地址  接下来的中间9位是页号
    //每一个表项 管4k 4k*512=2M
    //二级页表是4k 但是算下来只需要2k 后面2k是mmu硬件使用的 前面2k软件使用
    printk("pmd.11 = %lx\n", pmd2);
    pmd2 = *(unsigned long *)pmd2;
    printk("pmd.22 = %lx\n", pmd2);


    data = kmap_atomic(pfn_to_page(__phys_to_pfn(pmd2 & PHYS_MASK)));
    //映射目标页 每页4k


    print_hex_dump_bytes("walk.datax223xcv: ", DUMP_PREFIX_ADDRESS, (u8 *)((data)), 0x1000 ); 
    //目标页加上页偏移得到 最终的目的地址

kunmap_atomic(data);

运行日志:

pte = ffefe664
[   21.499818] *pte = 981e075f

ffefd640: 00 00 00 00 00 00 00 00 00 00 00 00 5f 57 1d 98  ............_W..
[   21.500150] walk.datax223xcv: ffefd650: 5f 67 1d 98 00 00 00 00 00 00 00 00 5f d7 1d 98  _g.........._...
[   21.500153] walk.datax223xcv: ffefd660: 5f c7 1d 98 5f 07 1e 98 00 00 00 00 00 00 00 00  _..._...........
[   21.500155] walk.datax223xcv: ffefd670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[   21.500158] walk.datax223xcv: ffefd680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    
    
    //(pte_t *)kmap_atomic(pmd_page(*(pmd)))     //使用高端内存映射
    
   //#define pmd_page(pmd)        pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))

    

        //pte_t *__pte = pte_offset_map(pte, 0x00);
        //printk("__pte = %lx\n", __pte);

        

        
        


        

        //print_hex_dump_bytes("walk.datax109: ", DUMP_PREFIX_ADDRESS, (u8 *)(task->mm->pgd), 0x4000 );


        //print_hex_dump_bytes("pgd.data1x: ", DUMP_PREFIX_ADDRESS, (u8 *)((unsigned int)pte&0xffffff00), 0x100 );

    

        

        pme = pte_to_pagemap_entry(pm, vma, addr, *pte);
        err = add_to_pagemap(addr, &pme, pm);
        if (!err){
            break;
        }
    }
    //printk("pagemap_pmd_range end!!! err = %d\n\n", err);
    pte_unmap_unlock(orig_pte, ptl);

    cond_resched();

    return err;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值