页表和缺页中断

虚拟内存空间的物理根本可以说就是页表了,没有页表虚拟地址空间是无法幻化出让人眼花缭乱的变化。

页表的样子

当然,页表本身已经够让人眼花缭乱了。那就先让我们来看一下页表的样子先。

            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     |          |
                   |                    |         pmd_offset() +---->|          |---------->+----------+
                   |                    |                            +----------+
                   |                    |                            |          |
                   |                    |                            |          |
                   |                    |                            |          |
                   |                    |     +----------+           |          |
                   |                    |     |          |           |          |
                   |                    | pud +----------+   *pud    |          |
                   |       pud_offset() +---->|          |---------->+----------+
                   |                          +----------+
                   |     +----------+         |          |
                   |     |          |         |          |
                   | pgd +----------+  *pgd   |          |
   pgd_offset(addr)+---->|          |-------->+----------+
                         +----------+
                         |          |
                         |          |
                         |          |
           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