- 论坛徽章:
- 3
|
回复 1# knull
这是一个将virutal address解析得到的pte entry的函数。 是一个从不直接映射的虚拟地址转换成物理地址的过程。
3967 static int __follow_pte(struct mm_struct *mm, unsigned long address,
3968 pte_t **ptepp, spinlock_t **ptlp)
3969 {
3970 pgd_t *pgd;
3971 pud_t *pud;
3972 pmd_t *pmd;
3973 pte_t *ptep;
3974
3975 pgd = pgd_offset(mm, address); // 根据mm->pgd找到的第一级page directory的物理地址, //再从解析地址知道是第几个 entry.从而获得下一级page directory的物理地址。
3976 if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) // 检测有没有引用下一级目录
3977 goto out;
3978
3979 pud = pud_offset(pgd, address); //和上面的过程差不多
3980 if (pud_none(*pud) || unlikely(pud_bad(*pud)))
3981 goto out;
3982
3983 pmd = pmd_offset(pud, address);//和上面的过程差不多
3984 VM_BUG_ON(pmd_trans_huge(*pmd));
3985 if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
3986 goto out;
3987
3988 /* We cannot handle huge page PFN maps. Luckily they don't exist. */
3989 if (pmd_huge(*pmd)) //可以不管
3990 goto out;
3991
3992 ptep = pte_offset_map_lock(mm, pmd, address, ptlp); // //和上面的过程差不多. 但要处理pte table可能在高端内存, 建立临时内核映射
3993 if (!ptep)
3994 goto out;
3995 if (!pte_present(*ptep)) //检查有没有映射page frame
3996 goto unlock;
3997 *ptepp = ptep; //找到了. **ptep就是要找到的物理页的起始。
3998 return 0;
3999 unlock:
4000 pte_unmap_unlock(ptep, *ptlp);
4001 out:
4002 return -EINVAL;
4003 }
把这个函数搞清楚, 你就知道这两个问题的答案了. |
|