读u-boot-2010.06代码

来源:互联网 发布:淘宝去同款排除王 编辑:程序博客网 时间:2024/04/28 20:37

(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;