开启MMU
在进入 __enable_mmu 的时候, r0中已经存放了控制寄存器c1的一些配置(在上一步中进行的设置), 但是并没有真正的打开mmu
此时,一些特定寄存器的值如下所示:
r0 = c1 parameters (用来配置控制寄存器的参数)
r4 = pgtbl (page table 的物理基地址)
r8 = machine info (struct machine_desc的基地址)
r9 = cpu id (通过cp15协处理器获得的cpu id)
r10 = procinfo (struct proc_info_list的基地址)
在 arch/arm/kernel/head.S 中:
155 __enable_mmu: //函数声明//
156 #ifdef CONFIG_ALIGNMENT_TRAP /* 根据相应的配置,
157 orr r0, r0, #CR_A * 设置r0中相应的位
158 #else *
159 bic r0, r0, #CR_A *
160 #endif *
161 #ifdef CONFIG_CPU_DCACHE_DISABLE *
162 bic r0, r0, #CR_C *
163 #endif *
164 #ifdef CONFIG_CPU_BPREDICT_DISABLE *
165 bic r0, r0, #CR_Z *
166 #endif *
167 #ifdef CONFIG_CPU_ICACHE_DISABLE *
168 bic r0, r0, #CR_I *r0将用来配置控制寄存器c1
169 #endif */
170 mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
171 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
172 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
173 domain_val(DOMAIN_IO, DOMAIN_CLIENT))
174 mcr p15, 0, r5, c3, c0, 0
175 mcr p15, 0, r4, c2, c0, 0
176 b __turn_mmu_on
177 ENDPROC(__enable_mmu)
.....................
190 .align 5
191 __turn_mmu_on:
192 mov r0, r0 //空操作
193 mcr p15, 0, r0, c1, c0, 0 //写CP15控制寄存器
194 mrc p15, 0, r3, c0, c0, 0 //读取ID寄存器
195 mov r3, r3
196 mov r3, r3
197 mov pc, r13 //r13中存储的是__switch_data,即跳转到
__switch_data
198 ENDPROC(__turn_mmu_on)
第195,196行的两个nop是非常重要的,因为在185行打开mmu操作之后,要等到3个cycle之后才会生效,这和arm的流水线有关系.
因而,在打开mmu操作之后的加了两个nop操作