TTBR0与TTBR1
ARMv7-A架构中有两个协处理器寄存器用来存放一级页表基地址(PGD),TTBR0和TTBR1(Translation table base register: 页表基地址寄存器)。其中,TTBR0用于存放用户空间的一级页表基址,TTBR1存放内核空间的一级页表基址。
以TTBR0为例,它的具体实现可以参阅<ARM Architecture Reference Manual(ARMv7-AR)> Page1709:
如果页表按照4K对齐,那么X=12
寄存器的访问地址(以Cortex-A9为例)
写入指令:
mcr p15, 0, r1, c2, c0, 0 @ TTB 0 mcr p15, 0, r7, c2, c0, 1 @ TTB 1
读出指令
mrc p15, 0, r1, c2, c0, 0 @ TTB 0 mrc p15, 0, r7, c2, c0, 1 @ TTB 1
Trace32写入指令
per.s c15:0x2 %long 0x24178059 // TTB0 per.s c15:0x102 %long 0x22304059 //TTB1
所有的内核进程地址空间的页表是共用一套的,所以TTBR1的值不会改变,TTB1段(Bit[31:x])永远等于init_mm->pgd:
(注意:init_mm->pgd存储的是虚拟地址,TTBR1需要存储物理地址,下图中两者的映射关系为(Phy:0x22300000)<-->(Vir:0xc0000000))
TTBR0代表了当前用户进程的页表基地址,其值会随着用户进程的切换而改变。所以TTB0段(Bit[31:x])等于当前任务(task_struct)*->(mm)*->pgd,
同样需要进行虚拟地址与物理地址关系的转换。
ARMv7-A根据TTBCR寄存器的N位决定使用TTBR0还是TTBR1:
N位在TTBCR寄存器的Bit[2:0],它也决定了TTBR寄存器的X(X=14-TTBCR.N)
根据描述:
如果 N==0,也就是 系统中没有配置 TTBCR的默认值,那么 ARM 总是使用 TTBR0来翻译虚拟地址 , 所以默认情况下,TTBR1是没有用的。
如果 N==1, 那么当 ARM 遇到大于等于0x80000000的地址时,就 需要使 用 TTBR1寄存器指向的映射表来转换虚拟地址 ,相应地 落在[0x0000000, 0x8000000]范围内的虚拟地址需要使用TTBR0映射表来翻译。
N=2, 临界地址是0x40000000,其余临界地址请参阅上图。