lowlevel_init初始化了13个寄存器来实现RAM时钟的初始化。lowlevel_init函数对于U-Boot从NAND Flash或NOR Flash启动的情况都是有效的。
U-Boot.lds链接脚本有如下代码:
.text:
{
cpu/arm920t/start.o
(.text)
board/samsung/mini2440/lowlevel_init.o(.text)
board/samsung/mini2440/nand_read.o(.text)
……
}
board/samsung/mini2440/lowlevel_init.o将被链接到cpu/arm920t/start.o后面,因此board/samsung/mini2440/lowlevel_init.o也在U-Boot的前4KB的代码中。
U-Boot在NAND Flash启动时,lowlevel_init.o将自动被读取到CPU内部4KB的内部RAM中。因此第137~146行的代码将从CPU内部RAM中复制寄存器的值到相应的寄存器中。
对于U-Boot在NOR Flash启动的情况,由于U-Boot连接时确定的地址是U-Boot在内存中的地址,而此时U-Boot还在NOR Flash中,因此还需要在NOR Flash中读取数据到RAM中。
由于NOR Flash的开始地址是0,而U-Boot的加载到内存的起始地址是TEXT_BASE,SMRDATA标号在Flash的地址就是SMRDATA-TEXT_BASE。
综上所述,lowlevel_init的作用就是将SMRDATA开始的13个值复制给开始地址[BWSCON]的13个寄存器,从而完成了存储控制器的设置。
(9)复制U-Boot第二阶段代码到RAM
cpu/arm920t/start.S原来的代码是只支持从NOR Flash启动的,经过修改现在U-Boot在NOR Flash和NAND Flash上都能启动了,实现的思路是这样的:
bl
bBootFrmNORFlash
/*
判断U-Boot是在NAND Flash还是NOR Flash启动
*/
cmp
r0, #0
/*
r0存放bBootFrmNORFlash函数返回值,若返回0表示NAND Flash启动,否则表示在NOR Flash启动
*/
beq
nand_boot
/*
跳转到NAND Flash启动代码
*/
/*
NOR Flash启动的代码
*/
b
stack_setup
/*跳过NAND Flash启动的代码 */
nand_boot:
/*
NAND Flash启动的代码
*/
stack_setup:
/*其他代码 */
其中bBootFrmNORFlash函数作用是判断U-Boot是在NAND Flash启动还是NOR Flash启动,若在NOR Flash启动则返回1,否则返回0。根据ATPCS规则,函数返回值会被存放在r0寄存器中,因此调用bBootFrmNORFlash函数后根据r0的值就可以判断U-Boot在NAND Flash启动还是NOR Flash启动。bBootFrmNORFlash函数在board/samsung/mini2440/nand_read.c中定义如下:
intbBootFrmNORFlash(void)
{
volatile unsigned int *pdw = (volatileunsigned int *)0;
unsigned int dwVal;
dwVal = *pdw;
/*先记录下原来的数据 */
*pdw = 0x12345678;
if (*pdw != 0x12345678)
/* 写入失败,说明是在NOR Flash启动
*/
{
return 1;
}
else
/* 写入成功,说明是在NAND Flash启动 */
{
*pdw = dwVal;
/* 恢复原来的数据 */
return 0;
}
}
无论是从NOR Flash还是从NAND Flash启动,地址0处为U-Boot的第一条指令“ b
start_code”。
对于从NAND Flash启动的情况,其开始4KB的代码会被自动复制到CPU内部4K内存中,因此可以通过直接赋值的方法来修改。
对于从NOR Flash启动的情况,NOR Flash的开始地址即为0,必须通过一定的命令序列才能向NOR Flash中写数据,所以可以根据这点差别来分辨是从NAND Flash还是NOR Flash启动:向地址0写入一个数据,然后读出来,如果发现写入失败的就是NOR Flash,否则就是NAND Flash。
下面来分析NOR Flash启动部分代码:
208
adr
r0, _start
/* r0<- current position of code
*/
209
ldr
r1, _TEXT_BASE
/*test if we run from flash or RAM */
/* 判断U-Boot是否是下载到RAM中运行,若是,则不用
再复制到RAM中了,这种情况通常在调试U-Boot时才发生 */
210
cmp
r0, r1
/*_start等于_TEXT_BASE说明是下载到RAM中运行 */
211
beq
stack_setup
212
/* 以下直到nand_boot标号前都是NOR Flash启动的代码 */
213
ldr
r2, _armboot_start
214
ldr
r3, _bss_start
215
sub
r2, r3, r2
/* r2<- size of armboot
*/
216
add
r2, r0, r2
/* r2<- source end address
*/
217
/* 搬运U-Boot自身到RAM中*/
218
copy_loop:
219
ldmia
r0!, {r3-r10}
/* 从地址为[r0]的NOR Flash中读入8个字的数据 */
220
stmia
r1!, {r3-r10}
/* 将r3至r10寄存器的数据复制给地址为[r1]的内存 */
221
cmp
r0, r2
/*until source end addreee [r2]
*/
222
ble
copy_loop
223
b
stack_setup
/* 跳过NAND Flash启动的代码 */ |