S&T的笔记 https://passport2.21ic.com/?600909 [收藏] [复制] [RSS] science and technology!

日志

U-Boot启动过程完全分析(5)

已有 854 次阅读2011-12-16 03:19 |个人分类:ARM|系统分类:ARM| U-Boot

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函数前先来看看一些重要的数据结构:


1gd_t结构体


       U-Boot使用了一个结构体gd_t来存储全局数据区的数据,这个结构体在include/asm-arm/global_data.h中定义如下:


typedef  struct     global_data {


       bd_t              *bd;


       unsigned long      flags;


       unsigned long      baudrate;


       unsigned long      have_console;      /* serial_init() was called */


       unsigned long      env_addr;     /* Address  of Environment struct */


       unsigned long      env_valid;    /* Checksum of Environment valid? */


       unsigned long      fb_base; /* base address of  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)


2bd_t结构体


       bd_tinclude/asm-arm.u/u-boot.h中定义如下:


typedef struct bd_info {


    int                bi_baudrate;               /* 串口通讯波特率 */


    unsigned long     bi_ip_addr;          /* IP 地址*/


    struct environment_s        *bi_env;              /* 环境变量开始地址 */


    ulong            bi_arch_number;      /* 开发板的机器码 */


    ulong            bi_boot_params;       /* 内核参数的开始地址 */


    struct                         /* RAM配置信息 */


    {


              ulong start;


              ulong size;


    }bi_dram[CONFIG_NR_DRAM_BANKS]; 


} bd_t;


       U-Boot启动内核时要给内核传递参数,这时就要使用gd_tbd_t结构体中的信息来设置标记列表。


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)