通过进程id找到对应的task_struct,就得到了cr3中存储着的页表首地址,然后同ing过页表找到最后页的物理地址
static pte_t *get_pte(struct task_struct *task, unsigned long address)
{
pgd_t* pgd;
p4d_t* p4d;
pud_t* pud;
pmd_t* pmd;
pte_t* pte;
struct mm_struct *mm = task->mm;
// mm里面存储了最高级页表的首地址,pgd_offset根据首地址和便宜算出下一级页表的首地址
pgd = pgd_offset(mm, address);
if(pgd_none(*pgd) || pgd_bad(*pgd))
{
printk("pgd is null\n");
return NULL;
}
p4d = p4d_offset(pgd, address);
if (p4d_none(*p4d) || p4d_bad(*p4d))
{
printk("p4d is null\n");
return NULL;
}
pud = pud_offset(p4d, address);
if (pud_none(*pud) || pud_bad(*pud))
{
printk("pud is null\n");
return NULL;
}
pmd = pmd_offset(pud, address);
if(pmd_none(*pmd) || pmd_bad(*pmd))
{
printk("pmd is null\n");
return NULL;
}
pte = pte_offset_kernel(pmd, address);
if(pte_none(*pte))
{
printk("pte is null\n");
return NULL;
}
return pte;
}
int main()
{
pte_t *pte = get_pte(task, addr);
// unsigned int level;
// pte_t *pte = lookup_address(addr, &level);
if(pte)
{
printk("evict\n");
pte->pte &= (~_PAGE_PRESENT);
}
}