(1)启动代码
.globl _start
_start:
b reset
...其它向量表
.balignl 16,0xdeadbeef //代码结束的一个标志
-----------------------------------------------------------------
_TEXT_BASE:
.word TEXT_BASE //TEXT_BASE在u-boot-2010.06/board/atmel/at91sam9260ek/config.mk中定义=0x23f00000
.globl _armboot_start //_TEXT_BASE = TEXT_BASE=_armboot_start
_armboot_start:
.word _start
.globl _bss_start
_bss_start:
.word __bss_start //在u-boot.ldr中有定义
.globl _bss_end
_bss_end:
.word _end //在u-boot.ldr中有定义
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de //这里先写了一个值,实际值在运行中计算
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de //这里先写了一个值,实际值在运行中计算
------------------------------------------------------------------
reset: //复位代码
...
relocate:
//这里判断程序是否是在Norflash中运行,是的话将程序(包含向量表,所有程序)搬移到RAM中的TEXT_BASE起始位置处。在编译程序的时候,这段代码的地址起始地址是在TEXT_BASE处的,也就是说中断向量表其实是在TEXT_BASE处的,代码搬移完成后就刚好是这个地址。在程序运行过程中,如果有复位发生,程序还是执行地址0x0处的复位代码,也要经过这复制代码,除非执行了remap。
stack_setup: //设置堆栈代码
ldr r0, _TEXT_BASE //将数据区域设置在代码的前面(低地址)
sub sp, r0, #128 //设置ABORD异常代码用的栈
sub r0, r0, #CONFIG_SYS_MALLOC_LEN //堆的大小
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE //全局结构体gd_t的大小,它指向代码执行后这里的r0
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) //IRQ和FIQ的栈
sub sp, r0, #12 //由于宏的原因,前面可能未设置abord异常栈
bic sp, sp, #7 //对齐栈
################
# 代码区 #
################
# ABORD栈 #
################
# 堆 #
################
# gd_t #
################
# gd->bd #
################
clear_bss:
//执行将bss段清0
跳转到start_armboot(C函数)
(2)arch/arm/lib/Board.c
void start_armboot()
{
init_fnc_t **init_fnc_ptr; //这是一个函数指针的指针,在下面用来遍历初始化函数列表
gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
//初始化上面提上的在内存区域的gd_t结构。这个gd在arch/arm/include/asm/Global_data.h中有定义,它保存在R8中。
//这里不知道为什么没有减去Abord栈区的大小
monitor_flash_len = _bss_start - _armboot_start;//FLASH镜像的大小,也就程序的大小
for(init_fnc_ptr ... //调用初始化列表,如果返回值不等于0,则出错
mem_malloc_init( ... //初始化堆
//初始化flash
display_flash_config (flash_init ());
/* initialize environment */
env_relocate ();//将flash中的环境变量拷贝到内存指针env_ptr中。
/* IP Address */
gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
stdio_init (); /* get the devices list going. */
jumptable_init ();
}
(3)环境变量
在Makefile中,XXX_CONFIG目标确定flash类型的配置
如使用“make at91sam9260ek_nandflash_config”会在config.h中生成代码"#define CONFIG_SYS_USE_NANDFLASH 1","CONFIG_SYS_USE_FLASH"表示使用norflash。
在Board.c中init_fnc_t *init_sequence[] = {...}有一个"env_init",这个函数调用用来初始化环境变量。它的定义是根据FLASH的配置来定义的,如定义了NANDFLASH,则Env_nand.c被包含进工程,里面定义了一个env_init()。“Env_flash.c”是使用norflash的文件。
Envvirmonment.h对环境变量的宏作出了判断和初始化。
Evn_common.c定义了一个“default_environment”,它是默认的环境变量。
CONFIG_ENV_ADDR_REDUND表示保存一个环境变量的备份,即在FLASH中有两份保存的环境变量。在env_init()中判断这两份数据的CRC。用gd->env_valid保存结果,为0表示CRC都错,为1表示其中一份有效,用gd->env_addr指向它。为2表示两份数据均有效(flash_addr->flags也一致,有关这个flag详细参考代码)。
在board.c的start_armboot函数的代码中将调用env_relocate ()重新将FLAHS中的环境变量保存到内存中。
ENV_IS_EMBEDDED表示env_ptr使用全局定义,这个变量未定义表示使用堆分配。
env_t在"Evn_common.c"中定义:
#define ENV_SIZE (CONFIG_ENV_SIZE - ENV_HEADER_SIZE)
typedef struct environment_s {
uint32_t crc; /* CRC32 over data bytes */
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
unsigned char flags; /* active/obsolete flags */
#endif
unsigned char data[ENV_SIZE]; /* Environment data */
} env_t;