paging_init 详解

发布时间 2023-07-01 19:00:34作者: 流水灯

建立二级页表项由 set_pte_ext 宏实现,实际上底层调用的是在内核启动之初获取的 list->processor->set_pte_ext,这是处理器相关的处理函数,对应的函数实现为 cpu_v7_set_pte_ext,在 arch/arm/mm/proc-v7-2level.S 中。

ENTRY(cpu_v7_set_pte_ext)
#ifdef CONFIG_MMU
    str    r1, [r0]            @ linux version

    bic    r3, r1, #0x000003f0
    bic    r3, r3, #PTE_TYPE_MASK
    orr    r3, r3, r2
    orr    r3, r3, #PTE_EXT_AP0 | 2

    tst    r1, #1 << 4
    orrne    r3, r3, #PTE_EXT_TEX(1)

    eor    r1, r1, #L_PTE_DIRTY
    tst    r1, #L_PTE_RDONLY | L_PTE_DIRTY
    orrne    r3, r3, #PTE_EXT_APX

    tst    r1, #L_PTE_USER
    orrne    r3, r3, #PTE_EXT_AP1

    tst    r1, #L_PTE_XN
    orrne    r3, r3, #PTE_EXT_XN

    tst    r1, #L_PTE_YOUNG
    tstne    r1, #L_PTE_VALID
    eorne    r1, r1, #L_PTE_NONE
    tstne    r1, #L_PTE_NONE
    moveq    r3, #0

 ARM(    str    r3, [r0, #2048]! )
 THUMB(    add    r0, r0, #2048 )
 THUMB(    str    r3, [r0] )
    ALT_SMP(W(nop))
    ALT_UP (mcr    p15, 0, r0, c7, c10, 1)        @ flush_pte
#endif
    bx    lr
ENDPROC(cpu_v7_set_pte_ext)

在 set_pte_ext 中,除了设置地址映射部分之外,还需要处理大量标志位的设置(比如 YOUNG、DIRTY bit),毕竟针对同一个页面,需要填充一个软件二级页表项和一个硬件二级页表项,硬件二级页表项给 MMU 使用,保存在 软件二级页表项 + 2048 地址处,在上面贴出的汇编代码中也有体现