页表和缺页中断
虚拟内存空间的物理根本可以说就是页表了,没有页表虚拟地址空间是无法幻化出让人眼花缭乱的变化。
页表的样子
当然,页表本身已经够让人眼花缭乱了。那就先让我们来看一下页表的样子先。
47 39 38 30 29 21 20 12 11 0
+------------------+------------------+------------------+------------------+---------------------+
|PML4 |Page Directory Ptr|Page Directory |Page Table |Offset |
+------------------+------------------+------------------+------------------+---------------------+
| | | |
| | | |
| | | |
| | | |
pgd_index(addr) | pud_index(addr) | pmd_index(addr) | pte_index(addr) | +----------+
| | | | | |
| | | | | |
| | | | +----------+
| | | pte_offset_map() +----> |pte |
| | | +----------+
| | | +----------+ | |
| | | | | | |
| | | | | | |
| | | pmd +----------+ | |
| | pmd_offset() +---->| *pmd |---------->+----------+
| | +----------+
| | | |
| | | |
| | | |
| | +----------+ | |
| | | | | |
| | pud +----------+ | |
| pud_offset() +---->| *pud |---------->+----------+
| +----------+
| +----------+ | |
| | | | |
| pgd +----------+ | |
pgd_offset(mm,addr)+---->| *pgd |-------->+----------+
+----------+
| |
| |
| |
mm->pgd ---> +----------+
看完了,其实也就是那样。原来觉得很难很神秘的东西,现在看来好像也就那样。
页表的填写
那这张表怎么填写呢?当然途径不止一条,不过最重要的就是缺页中断了。
总的来讲就是按照虚拟地址来遍历整个页表,根据不同PTE的状态做不同的处理。
handle_mm_fault
hugetlb_fault
__handle_mm_fault
// pmd level
create_huge_pmd
do_huge_pmd_numa_page
wp_huge_pmd
// pte level
handle_pte_fault
// empty pte
do_anonymous_page
do_fault
// other
do_swap_page
do_numa_page
do_wp_page
页表的释放
有借必有还,有写必有擦。
看过了页表构造的过程(虽然糙了点),那也该看看页表释放的过程。当然我不确定是不是有很多地方可以做释放的动作,不过下面这个函数是我找到的接口之一。
unmap_region
unmap_vmas()
free_pgtables()
其中unmap_vmas释放了真正对应的内存,而free_pgtables才释放页表。
写到这里,感觉写完了,估计是很多细节自己还不知道。没事,留着以后有新发现再来挖掘。
Last updated