start_armboot

============================================
作者:yuanlulu
http://blog.csdn.net/yuanlulu


版权没有,但是转载请保留此段声明
============================================


第一个c函数位于arch/arm/lib/board.c

 

start_armboot会马上申请三块空间,一块用来分配给malloc管理,一份用来存储gd_t,一份用来存储bd_t。

他们在RAM中内存布局如上图所示。

 

void start_armboot (void)
{
 init_fnc_t **init_fnc_ptr;
 char *s;
 int delay = 100000;
 int  *p3_output_set, *p3_output_clr;


#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
 unsigned long addr;
#endif

 

 /* Pointer is writable since we allocated a register for it */
 gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));     //gd指向uboot之前的地址。
 /* compiler optimization barrier needed for GCC >= 3.4 */


 __asm__ __volatile__("": : :"memory");

 memset ((void*)gd, 0, sizeof (gd_t));
 gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));  //gd->bd指向gd之前。


 memset (gd->bd, 0, sizeof (bd_t));

 gd->flags |= GD_FLG_RELOC;

 monitor_flash_len = _bss_start - _armboot_start;

 
 /*循环调用init_sequence的初始化函数*/
 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
  if ((*init_fnc_ptr)() != 0) {
   hang ();
   
  }

 }

 

 /* armboot_start is defined in the board-specific linker script */
 mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,
   CONFIG_SYS_MALLOC_LEN);//初始化用作malloc的内存空间。

 

#ifndef CONFIG_SYS_NO_FLASH     //目前3250不支持nor flash.
 /* configure available FLASH banks */
 display_flash_config (flash_init ());
#endif /* CONFIG_SYS_NO_FLASH */

#ifdef CONFIG_VFD                //3250不支持VFD              
# ifndef PAGE_SIZE
#   define PAGE_SIZE 4096
# endif


 /*
  * reserve memory for VFD display (always full pages)
  */
 /* bss_end is defined in the board-specific linker script */
 addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
 vfd_setmem (addr);
 gd->fb_base = addr;
#endif /* CONFIG_VFD */

#ifdef CONFIG_LCD   //3250不支持LCD
 /* board init may have inited fb_base */
 if (!gd->fb_base) {
#  ifndef PAGE_SIZE
#    define PAGE_SIZE 4096
#  endif


  /*
   * reserve memory for LCD display (always full pages)
   */
  /* bss_end is defined in the board-specific linker script */
  addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
  lcd_setmem (addr);
  gd->fb_base = addr;
 }
#endif /* CONFIG_LCD */

 

#if defined(CONFIG_CMD_NAND)
 puts ("NAND:  ");
 nand_init();  /* go init the NAND */调用driver/mtd/nand/nand.c.打印:NAND:  256 MiB
#endif
 //puts("NAND init end /n");
#if defined(CONFIG_CMD_ONENAND)  3250不支持
 onenand_init();
#endif

 

#ifdef CONFIG_HAS_DATAFLASH 3250不支持
 AT91F_DataflashInit();
 dataflash_print_info();
#endif

 

 /* initialize environment */
 env_relocate ();   //祥见下面的分析

#ifdef CONFIG_VFD
 /* must do this after the framebuffer is allocated */
 drv_vfd_init();
#endif /* CONFIG_VFD */

#ifdef CONFIG_SERIAL_MULTI
 serial_initialize();
#endif

 

 /* IP Address */
 gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); //获取环境变量的ip地址填充gd->bd->bi_ip_addr

 stdio_init (); /* get the devices list going. */ //common/stdio.c 初始化stdio设备dev,将串口的接口注册进dev系统。

 jumptable_init ();//初始化gd->jt跳转表(common/export.c)。跳转表保存的是stdio的各个函数指针

#if defined(CONFIG_API)
 /* Initialize API */
 api_init ();
#endif

 

 console_init_r (); /* fully init console as a device *//(common/console.c)初始化stdin/stdout/和stderr,都指向stdio_init注册的stdio dev。gd->flags |= GD_FLG_DEVINIT;
/*输出信息:
In:    serial
Out:   serial
Err:   serial*/
#if defined(CONFIG_ARCH_MISC_INIT)
 /* miscellaneous arch dependent initialisations */
 arch_misc_init ();
#endif


#if defined(CONFIG_MISC_INIT_R)
 /* miscellaneous platform dependent initialisations */
 misc_init_r ();
#endif

 /* enable exceptions */
 enable_interrupts ();    

 /* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_TI_EMAC
 /* XXX: this needs to be moved to board init */
extern void davinci_eth_set_mac_addr (const u_int8_t *addr);
 if (getenv ("ethaddr")) {
  uchar enetaddr[6];
  eth_getenv_enetaddr("ethaddr", enetaddr);
  davinci_eth_set_mac_addr(enetaddr);
 }
#endif

 

#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
 /* XXX: this needs to be moved to board init */
 if (getenv ("ethaddr")) {
  uchar enetaddr[6];
  eth_getenv_enetaddr("ethaddr", enetaddr);
  smc_set_mac_addr(enetaddr);
 }
#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */

 /* Initialize from environment */
 if ((s = getenv ("loadaddr")) != NULL) {                       //3250目前不支持
  load_addr = simple_strtoul (s, NULL, 16);
 }
#if defined(CONFIG_CMD_NET)
 if ((s = getenv ("bootfile")) != NULL) {   //“uImage”内核镜像名
  copy_filename (BootFile, s, sizeof (BootFile));
 }
#endif

 

#ifdef BOARD_LATE_INIT
 board_late_init ();
#endif

#ifdef CONFIG_GENERIC_MMC
 puts ("MMC:   ");
 mmc_initialize (gd->bd);
#endif

#ifdef CONFIG_BITBANGMII
 bb_miiphy_init();
#endif
#if defined(CONFIG_CMD_NET)
#if defined(CONFIG_NET_MULTI)
 puts ("Net:   ");
#endif


 eth_initialize(gd->bd);
#if defined(CONFIG_RESET_PHY_R)
 debug ("Reset Ethernet PHY/n");
 reset_phy();
#endif
#endif
 
 /* main_loop() can return to retry autoboot, if so just run it again. */
 for (;;) {
  main_loop ();
 }

 /* NOTREACHED - no way out of command loop except booting */
 
}

void hang (void)
{
 puts ("### ERROR ### Please RESET the board ###/n");
 for (;;);
}

2.env_relocate ()  
void env_relocate (void)
{
。。。。。。。。。。
#ifdef ENV_IS_EMBEDDED
。。。。。。。。。。。。。。。。。。。
#else
 /*
  * We must allocate a buffer for the environment
  */
 env_ptr = (env_t *)malloc (CONFIG_ENV_SIZE);   //在内存的malloc区域申请一块内存存放环境变量。
 DEBUGF ("%s[%d] malloced ENV at %p/n", __FUNCTION__,__LINE__,env_ptr);
#endif

 if (gd->env_valid == 0) {
#if defined(CONFIG_GTH) || defined(CONFIG_ENV_IS_NOWHERE) /* Environment not changable */
  puts ("Using default environment/n/n");
#else
  puts ("*** Warning - bad CRC, using default environment/n/n");
  show_boot_progress (-60);
#endif
  set_default_env();
 }
 else {
  env_relocate_spec ();  init_sequence说到了,gd->env_valid 总为1,所以会执行这个路径。
 }
 gd->env_addr = (ulong)&(env_ptr->data);  //初始化gd->env_addr

#ifdef CONFIG_AMIGAONEG3SEs
 disable_nvram();
#endif
}
由于smartarm3250中定义了CONFIG_CMD_NAND,common/目录下的makefile会选择性的编译env_nand.c而不是其他的文件。

env_relocate_spec ();  就定义在env_nand.c。
void env_relocate_spec (void)
{
#if !defined(ENV_IS_EMBEDDED)
 int ret;

 ret = readenv(CONFIG_ENV_OFFSET, (u_char *) env_ptr);  //CONFIG_ENV_OFFSET是在smartarm3250.h中定义的表示环境变量在flash中的偏移位置。,env_ptr是本文件内的一个全局指针。
 if (ret)
  return use_default();

 if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)
  return use_default();
#endif /* ! ENV_IS_EMBEDDED */
}
#endif /* CONFIG_ENV_OFFSET_REDUND */

#if !defined(ENV_IS_EMBEDDED)
static void use_default()
{
 puts ("*** Warning - bad CRC or NAND, using default environment/n/n");
 set_default_env();
}
#endif


readenv函数将从flash中读取环境变量到env_ptr。
如果读取失败或者校验错误,则使用default_environment的内容填充env_ptr->data,并打印以下信息:*** Warning - bad CRC or NAND, using default environment/n/n
无论env_ptr->data指向的内容是从flash读出的,还是填充的default_environment,gd->env_addr = (ulong)&(env_ptr->data); 

default_environment是根据宏生成的环境变量,从flash中读出的是用户修改过的环境变量,两者可能不一样。

 

 

总结:init_sequence之后的函数基本没有涉及到硬件初始化,大多是进行环境变量和数据结构的初始化。虽然函数很长,但是大部分都没有执行。

 

对与两个全局结构体的初始化过程如下表所示:

arch/arm/include/asm/global_data.h 意义赋值顺序 第一次赋值 第二次赋值 第一次赋值函数 第二次
typedef struct global_data {uboot全局信息结构体     
bd_t  *bd;指向板级信息结构体<0>(bd_t*)((char*)gd - sizeof(bd_t)); arch/arm/lib/board.c/start_armboo 
unsigned long flags;标志变量<0><13>|= GD_FLG_RELOC|= GD_FLG_DEVINITarch/arm/lib/board.c/start_armboocommon/console.c/console_init_r
unsigned long baudrate;终端波特率<5>CONFIG_BAUDRATE(115200) arch/arm/lib/board.c/init_baudrate 
unsigned long have_console;是否已经调用了serial_init()<7>1 common/console.c/console_init_f 
unsigned long env_addr;环境变量结构体的地址<3><10>(ulong)&default_environment[0];(ulong)&(env_ptr->data)common/env_nand.c/env_initcommon/env_common.c/env_relocate 
unsigned long env_valid;环境变量的校验码是否正确<4>1 common/env_nand.c/env_init 
unsigned long fb_base; 帧缓冲的基地址     
void**jt;stdio函数的指针跳转表<12>malloc(XF_MAX * sizeof(void *)) common/export.c/jumptable_init 
} gd_t;      
       
       
       
typedef struct bd_info {板级配置信息结构体     
int   bi_baudrate;串口终端波特率<6>CONFIG_BAUDRATE(115200) arch/arm/lib/board.c/init_baudrate 
unsigned long bi_ip_addr;ip地址<11> getenv_IPaddr ("ipaddr") arch/arm/lib/board.c/start_armboo 
struct environment_s        *bi_env;环境变量结构体的地址     
 ulong         bi_arch_number; 板子编号<1>MACH_TYPE_UBOOTSYS(MACH_TYPE_LPC3XXX) board/zhiyuan/smartarm3250/smart3250.c/board_init 
ulong         bi_boot_params;板子启动参数<2>CFG_ENV_ADDR(0x80000100) board/zhiyuan/smartarm3250/smart3251.c/board_init 
 struct {RAM描述结构体     
        ulong start;开始地址<8>PHYS_SDRAM_1;在smartarm3250.h中,起始地址 board/zhiyuan/smartarm3250/smart3250.c/dram_init 
        ulong size;RAM大小<9> 0x04000000; /* 64M ,RAM大小*/ board/zhiyuan/smartarm3250/smart3250.c/dram_init 
}bi_dram[CONFIG_NR_DRAM_BANKS];      
} bd_t;      

 

分析,bd的bi_env因该指向env_ptr的,可是程序中没有给它赋值,也没有使用。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值