标题:
U-Boot启动过程完全分析(5)
[打印本页]
作者:
yuyang911220
时间:
2015-9-22 16:14
标题:
U-Boot启动过程完全分析(5)
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
启动的代码
*/
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0