标题:
U-Boot启动过程完全分析(7)
[打印本页]
作者:
yuyang911220
时间:
2015-9-22 16:27
标题:
U-Boot启动过程完全分析(7)
完整代码见
board/samsung/mini2440/nand_read.c
中的
nand_read_ll
函数,这里给出伪代码:
int nand_read_ll(unsigned char *buf,unsigned long start_addr, int size)
{
//
根据
NFCONF
寄存器的
Bit3
来区分
2
种
NAND Flash
if(NFCONF & 0x8 )
/* Bit
是
1
,表示是
2KB/page
的
NAND Flash */
{
////////////////////////////////////
读取
2K block
的
NAND Flash
////////////////////////////////////
}
else
/* Bit
是
0
,表示是
512B/page
的
NAND Flash */
{
/////////////////////////////////////
读取
512B block
的
NAND Flash
/////////////////////////////////////
}
return 0;
}
(
10
)设置堆栈
/*
设置堆栈
*/
stack_setup:
ldr
r0, _TEXT_BASE
/* upper 128 KiB: relocated uboot
*/
sub
r0, r0, #CONFIG_SYS_MALLOC_LEN
/* malloc area
*/
sub
r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /*
跳过全局数据区
*/
#ifdef CONFIG_USE_IRQ
sub
r0, r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub
sp, r0, #12
/*leave 3 words for abort-stack
*/
只要将
sp
指针指向一段没有被使用的内存就完成栈的设置了。根据上面的代码可以知道
U-Boot
内存使用情况了,如下图所示:
图
2.2 U-Boot
内存使用情况
(
11
)清除
BSS
段
clear_bss:
ldr
r0, _bss_start
/* BSS
段开始地址,在
u-boot.lds
中指定
*/
ldr
r1, _bss_end
/*BSS
段结束地址,在
u-boot.lds
中指定
*/
mov
r2, #0x00000000
clbss_l:str
r2, [r0]
/*
将
bss
段清零
*/
add
r0, r0, #4
cmp
r0, r1
ble
clbss_l
初始值为
0
,无初始值的全局变量,静态变量将自动被放在
BSS
段。应该将这些变量的初始值赋为
0
,否则这些变量的初始值将是一个随机的值,若有些程序直接使用这些没有初始化的变量将引起未知的后果。
(
12
)跳转到第二阶段代码入口
ldr
pc, _start_armboot
_start_armboot:
.word
start_armboot
跳转到第二阶段代码入口
start_armboot
处。
1.1.2
U-Boot
启动第二阶段代码分析
start_armboot
函数在
lib_arm/board.c
中定义,是
U-Boot
第二阶段代码的入口。
U-Boot
启动第二阶段流程如下:
图
2.3 U-Boot
第二阶段执行流程
在分析
start_armboot
函数前先来看看一些重要的数据结构:
(
1
)
gd_t
结构体
U-Boot
使用了一个结构体
gd_t
来存储全局数据区的数据,这个结构体在
include/asm-arm/global_data.h
中定义如下:
typedef
struct
global_data {
bd_t
*bd;
unsignedlong
flags;
unsignedlong
baudrate;
unsignedlong
have_console;
/* serial_init() was called */
unsignedlong
env_addr;
/* Address
of Environmentstruct */
unsignedlong
env_valid;
/* Checksum of Environment valid? */
unsignedlong
fb_base;
/* base address of frame buffer */
void
**jt;
/* jump table */
} gd_t;
U-Boot
使用了一个存储在寄存器中的指针
gd
来记录全局数据区的地址:
#define DECLARE_GLOBAL_DATA_PTR
register volatile gd_t *gd asm("r8")
DECLARE_GLOBAL_DATA_PTR
定义一个
gd_t
全局数据结构的指针,这个指针存放在指定的寄存器
r8
中。
这个声明也避免编译器把
r8
分配给其它的变量。
任何想要访问全局数据区的代码,只要代码开头加入
“DECLARE_GLOBAL_DATA_PTR”
一行代码,然后就可以使用
gd
指针来访问全局数据区了。
根据
U-Boot
内存使用图中可以计算
gd
的值:
gd = TEXT_BASE
-
CONFIG_SYS_MALLOC_LEN
-
sizeof(gd_t)
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0