在上一篇中讲完了lowlevel_init中对相应模式的设置、在最后对MMU进行了初始化。
那在这一篇就把使能MMU的过程描述了。
1、设置访问域
1 after_copy: //这里怎么就after了、我们可还没有copy呢
//剧透一下,后面会补充copy相关的代码,此处暂且跳过
2 #ifdef CONFIG_ENABLE_MMU //
3 enable_mmu:
4 /* enable domain access */
5 ldr r5, =0x0000ffff
6 mcr p15, 0, r5, c3, c0, 0 /* load domain access register */
//又是协处理器、查表知:寄存器为 Domain Access Control Register
7 //查位设置知道:此处将 D7 ~ D0 的位设置成允许管理,不再询问权限
2、设置TTB寄存器()
8 /* Set the TTB register */
9 ldr r0, _mmu_table_base //稍后解析
10 ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE //第一篇已叙述,0x57e0_0000
11 ldr r2, =0xfff00000
12 bic r0, r0, r2 //清楚段首偏移
13 orr r1, r0, r1 //包含 r1 的段首偏移和 r0 的段内偏移
14 mcr p15, 0, r1, c2, c0, 0 //查协处理器表
//Translation Table Base 转换表的基址
15
这里的 _mmu_table_base 最终定义为
#ifdef CONFIG_ENABLE_MMU
_mmu_table_base:
.word mmu_table
#endif
mmu_table 就是我们在 lowlevel_init 中最后介绍的制表代码的头。
3、使能MMU的准备工作
16 /* Enable the MMU */
17 mrc p15, 0, r0, c1, c0, 0 //Control Register
//见上一节、此时 r0 最低位为 0
18 orr r0, r0, #1 /* Set CR_M to enable MMU */
//将 r0 最低位置 1
19
20 /* Prepare to enable the MMU */
21 adr r1, skip_hw_init //小范围地址取值
22 and r1, r1, #0x3fc //保留段内偏移
23 ldr r2, _TEXT_BASE //保留代码段偏移
24 ldr r3, =0xfff00000
25 and r2, r2, r3 //保留段首偏移
26 orr r2, r2, r1 //r2 取到相应段内 skip_hw_init 偏移地址
27 b mmu_enable //就在下面
28
4、使能MMU(ps:不要被上一段的英文注释迷惑了)
29 .align 5
30 /* Run in a single cache-line */
31 mmu_enable:
32 //r0 只需要知道最低位为 1 就好
33 mcr p15, 0, r0, c1, c0, 0
//协处理器、查表
//在下面贴出相应寄存器的最低位
34 nop
35 nop
36 mov pc, r2 //跳转到 skip_hw_init 的位置
//个人感觉不要也没有什么问题,和之前的 mmu_disable 差不多的方法
37 #endif
寄存器最低位控制信息
[0] M bit Banked Enables the MMU.
0 = MMU disabled, reset value.
1 = MMU enabled.
此时、MMU才真正使能了。
在此处小回顾一下,之前的 NAND FLASH 和这里的 MMU 都是由协处理器使能的。