(7)关闭MMU,cache
接着往下看:
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl
cpu_init_crit
#endif
cpu_init_crit这段代码在U-Boot正常启动时才需要执行,若将U-Boot从RAM中启动则应该注释掉这段代码。
下面分析一下cpu_init_crit到底做了什么:
320
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
321
cpu_init_crit:
322
/*
323
* 使数据cache与指令cache无效 */
324
*/
325
mov
r0, #0
326
mcr
p15, 0, r0, c7, c7, 0
/* 向c7写入0将使ICache与DCache无效*/
327
mcr
p15, 0, r0, c8, c7, 0
/* 向c8写入0将使TLB失效 */
328
329
/*
330
* disable MMU stuff and caches
331
*/
332
mrc
p15, 0, r0, c1, c0, 0
/*
读出控制寄存器到r0中
*/
333
bic
r0, r0, #0x00002300
@ clearbits 13, 9:8 (--V- --RS)
334
bic
r0, r0, #0x00000087
@ clearbits 7, 2:0 (B--- -CAM)
335
orr
r0, r0, #0x00000002
@ setbit 2 (A) Align
336
orr
r0, r0, #0x00001000
@ setbit 12 (I) I-Cache
337
mcr
p15, 0, r0, c1, c0, 0
/*
保存r0到控制寄存器
*/
338
339
/*
340
* before relocating, we have to setup RAMtiming
341
* because memory timing is board-dependend,you will
342
* find a lowlevel_init.S in your boarddirectory.
343
*/
344
mov
ip, lr
345
346
bl
lowlevel_init
347
348
mov
lr, ip
349
mov
pc, lr
350
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
代码中的c0,c1,c7,c8都是ARM920T的协处理器CP15的寄存器。其中c7是cache控制寄存器,c8是TLB控制寄存器。325~327行代码将0写入c7、c8,使Cache,TLB内容无效。
第332~337行代码关闭了MMU。这是通过修改CP15的c1寄存器来实现的,先看CP15的c1寄存器的格式(仅列出代码中用到的位):
表 2.3 CP15的c1寄存器格式(部分)
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | . | . | V | I | . | . | R | S | B | . | . | . | . | C | A | M |
各个位的意义如下:
V :
表示异常向量表所在的位置,0:异常向量在0x00000000;1:异常向量在 0xFFFF0000
I :
0 :关闭ICaches;1 :开启ICaches
R、S : 用来与页表中的描述符一起确定内存的访问权限
B :
0 :CPU为小字节序;1 : CPU为大字节序
C :
0:关闭DCaches;1:开启DCaches
A :
0:数据访问时不进行地址对齐检查;1:数据访问时进行地址对齐检查
M :
0:关闭MMU;1:开启MMU
332~337行代码将c1的 M位置零,关闭了MMU。
(8)初始化RAM控制寄存器
其中的lowlevel_init就完成了内存初始化的工作,由于内存初始化是依赖于开发板的,因此lowlevel_init的代码一般放在board下面相应的目录中。对于mini2440,lowlevel_init在board/samsung/mini2440/lowlevel_init.S中定义如下:
45
#define BWSCON
0x48000000
/* 13个存储控制器的开始地址 */
……
129
_TEXT_BASE:
130
.word
TEXT_BASE
131
132
.globl lowlevel_init
133
lowlevel_init:
134
/* memory control configuration*/
135
/* make r0 relative the currentlocation so that it */
136
/* reads SMRDATA out of FLASHrather than memory ! */
137
ldr
r0, =SMRDATA
138
ldr
r1, _TEXT_BASE
139
sub
r0, r0, r1
/*SMRDATA减 _TEXT_BASE就是13个寄存器的偏移地址 */
140
ldr
r1, =BWSCON
/* Bus WidthStatus Controller */
141
add
r2, r0, #13*4
142
0:
143
ldr
r3, [r0], #4
/*将13个寄存器的值逐一赋值给对应的寄存器*/
144
str
r3, [r1], #4
145
cmp
r2, r0
146
bne
0b
147
148
/* everything is fine now */
149
mov
pc, lr
150
151
.ltorg
152
/* the literal pools origin */
153
154
SMRDATA:
/*
下面是13个寄存器的值
*/
155
.word
… …
156
.word
… …
… … |