首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

U-boot启动分析 -arm(4)

U-boot启动分析 -arm(4)

void start_armboot (void)
{
      DECLARE_GLOBAL_DATA_PTR;
//此宏定义了一个gd_t类型的指针 *gd,并指名用r8寄存器来存储:
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm("r8")
      ulong size;
      init_fnc_t **init_fnc_ptr;
      char *s;
     
      gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN -sizeof(gd_t));
//
此C语句引用的是start.S中的地址标号_armboot_start,但是得到的却是其中所指的变量_start的值(在RAM中,_start
= 0x33F80000)。   Ps:   _armboot_start:    .word_start
//gd是全局变量,位置在堆栈区以下(低地址):
typedef struct global_data {
    bd_t *bd;
    unsigned long flags;
    unsigned long baudrate;
    unsigned longhave_console;
    unsigned long reloc_off;     
    unsigned long env_addr;
    unsigned longenv_valid;
    unsigned long fb_base;
#ifdef CONFIG_VFD
    unsigned char vfd_type;
#endif
#if 0
    unsigned long cpu_clk;
    unsigned long bus_clk;
    unsigned long ram_size;
    unsigned longreset_status;
#endif
    void **jt;
} gd_t;
     
      __asm__ __volatile__("": : :"memory");
      memset ((void*)gd, 0, sizeof (gd_t));
      gd->bd = (bd_t*)((char*)gd -sizeof(bd_t));    //得到bd的起点
      memset (gd->bd, 0, sizeof(bd_t));
      monitor_flash_len = _bss_start -_armboot_start;
     
      for (init_fnc_ptr = init_sequence;*init_fnc_ptr; ++init_fnc_ptr) {
           if((*init_fnc_ptr)() != 0) {
                 hang();
           }
      }
     
      size = flash_init ();      //初始化Norflash的函数,函数实现在下面
      display_flash_config (size);   //打印到控制台:Flash: 512 kB
     
      mem_malloc_init (_armboot_start -CFG_MALLOC_LEN);      //将CFG_MALLOC_LEN区域用memset函数清零(直接往目的地址写0)
     
      env_relocate ();      //刚才的初始化函数中有一个是env_init(),根据CRC校验来初始化gd->env_addr变量(自己设定的还是初始值),此函数是作用是将环境变量值从某个flash和RAM之间的拷贝。下图描述了ENV的初始化过程:


      gd->bd->bi_ip_addr= getenv_IPaddr ("ipaddr");
     
         {
       int i;
       ulongreg;
       char *s,*e;
       uchartmp[64];
       i = getenv_r("ethaddr", tmp, sizeof (tmp));
       s = (i> 0) ? tmp : NULL;
       for (reg = 0;reg  6; ++reg) {
         gd->bd->bi_enetaddr[reg]= s ? simple_strtoul (s, &e, 16) : 0;
          if (s)
             s = (*e) ?e + 1 : e;
       }
    }
      devices_init ();
      jumptable_init ();
      console_init_r ();
      enable_interrupts ();
     
      if ((s = getenv ("loadaddr")) != NULL) {
            load_addr =simple_strtoul (s, NULL, 16);
      }
     
      for (;;) {
            main_loop();
      }
     
}


      }
     
}
继承事业,薪火相传
返回列表