uboot启动流程分析之二

Board.c

uboot启动流程分析之二_第1张图片

·  #ifdefined(CONFIG_ARCH_CPU_INIT)
·       arch_cpu_init,
·  #endif
·       board_init,
·  #ifdefined(CONFIG_USE_IRQ)
·      interrupt_init,
·  #endif
·  timer_init,
·  #ifdef CONFIG_FSL_ESDHC
·  get_clocks,
·  #endif
·  env_init,
·  init_baudrate,
·  serial_init,
·  console_init_f,
·  display_banner,
·  #if defined(CONFIG_DISPLAY_CPUINFO)
·  print_cpuinfo,
·  #endif
·  #if defined(CONFIG_DISPLAY_BOARDINFO)
·  checkboard,
·  #endif
·  dram_init,
·  arch_usb_init,
·  NULL,
·  };






//入口

·  void start_armboot (unsigned *pRunning, unsigned startup_flag, unsigned resume_code) 
·  { 
·   init_fnc_t ** init_fnc_ptr; /*双重指针*/ 
 
· 全局数据变量分配空间  
·   gd = (gd_t*)(_armboot_start – CONFIG_BOOTHEAD_GAP 
·   - CONFIG_SYS_MALLOC_LEN – sizeof(gd_t)); 
 /*先在内存中为gd_t分配了空间,然后让前面定义的gd指针指向它的首地址*/  
· /* 接着也分配了bd_t结构体的空间,这个空间在gd_t之下,然后将gd_t中的bd指针赋值为它的首地址。*/ 
·  
·  memset ((void*)gd, 0, sizeof (gd_t));
//开发板的数据变量 分配空间
·   gd->bd =(bd_t*)((char*)gd-sizeof(bd_t));
·  memset(gd->bd,0,sizeof (bd_t));
·  insert_ddr_layout((unsigned int)gd->bd,
·  (unsigned int)((char *)gd+sizeof(gd_t)),"globaldata");
·  gd->flags|=GD_FLG_RELOC;


//结构体  具体内容
gd 全局数据变量指针,它保存了u-boot运行需要的全局数据,类型定义:
Typedef struct global_data {
 bd_t   *bd;              //board data pointor  开发板数据指针
 unsigned long flags;  //指示标志,如设备已经初始化标志等。
 unsigned long baudrate; //串口波特率
 unsigned long have_console; /* 串口初始化标志*/
 unsigned long reloc_off;
/* 重定位偏移,就是实际定向的位置与编译连接时指定的位置之差,一般为0 */
 unsigned long env_addr; /* 环境参数地址*/
 unsigned long env_valid; /* 环境参数CRC检验有效标志 */
 unsigned long fb_base; /* base address of frame buffer */
  #ifdef CONFIG_VFD
 unsigned char vfd_type; /* display type */
  #endif
 void   **jt;   /* 跳转表,函数调用地址登记 */
 } gd_t;

typedef  struct bd_info {
 int    bi_baudrate     /* 串口波特率 */
 unsigned long bi_ip_addr;    /* IP 地址 */
unsigned char bi_enetaddr[6]; /* MAC地址*/
 struct environment_s    *bi_env;
 ulong     bi_arch_number; /* unique id for this board */
 ulong     bi_boot_params; /* 启动参数 */
 struct     /* RAM 配置 */
 {
          ulong start;
           ulong size;
 }bi_dram[CONFIG_NR_DRAM_BANKS];

 } bd_t;





·        /*init_sequence就是一个双重指针*/
·   /*init_fnc_t  *init_sequence[]*/
·                        /*     *init_fnc_ptr是判断函数指针是否存在*/
·   /*++init_fnc_ptr是指向数组的下一个元素,即指向下一个函数指针*/
·  for (init_fnc_ptr =init_sequence;*init_fnc_ptr; ++init_fnc_ptr){
·  if ((*init_fnc_ptr)() != 0) { /*用双重函数指针调用数组中的这些函数*/
·  hang ();/*如果函数返回为非0,则调用hang()
·  }
·  }

//设置GPIO
HI_DRV_GPIO_Init();

·  /* for USB power off,GPIO9_3*/
·  HI_DRV_GPIO_SetDirBit(75, 0);
·  HI_DRV_GPIO_WriteBit(75,0);
·  /* for SATA power off ,GPIO10_4*/
·  HI_DRV_GPIO_SetDirBit(84, 0);
·  HI_DRV_GPIO_WriteBit(84,0);

....

·  ReSwitch:
·  switch (startup_flag & 0xff)
·  {
·        case 0xce:           /* recovery */
·  udelay (1000000);        //1000ms
·  HI_DRV_GPIO_ReadBit(47,&power_detect);
·  if(power_detect == 0){
·  printf(". Mode RECOVERY\n.\n");
·  standby_before_get_kernel(1);          //待机
·  recovery_flag = 0x87921111;
· break;
·  }else{
·  printf(". Mode FAKE RECOVERY, Go On with COLD RESET!\n.\n");
·  startup_flag = 0xbb;
·  goto ReSwitch;
·  }
·  
·  case   0xba:          /*resume*/
·  printf(".mode %s\n.\n",pRunning<0xf0000000?"RESUME":"GO FROM RAM"); 
·  startmce_before_boot_kernel();
·  break;
·  
· case 0xbb:             /* cold reset*/
· //printf("g_runnning_addr=%p\n", g_running_addr);
·  printf(".mode%s\n.\n",pRunning>0xf0000000?"COLD RESET":"ROM XMODEM");
·  standby_before_get_kernel(pRunning<0xf0000000);
· break;
·  
· case 0xbc:             /*power off*/
·  printf(".Mode POWER OFF\n.\n");
·  standby_before_get_kernel(0);
·  break;
·  
·  case  0xbd:        /*usb updatefail*/
·  printf(".Mode UPDATE FAIL\n.\n");
· HI_DRV_GPIO_WriteBit(42,0);//5_2
·  HI_DRV_GPIO_WriteBit(44,1);//5_4
·  HI_DRV_GPIO_WriteBit(72,1);//9_0
· for (;;);
·  break;
·  
·  case 0xbe:/* usb update success */
·  printf(". Mode UPDATED\n.\n");
·  HI_DRV_GPIO_WriteBit(42,0);
·  HI_DRV_GPIO_WriteBit(44,1);
·  HI_DRV_GPIO_WriteBit(73,1);
·  for(;;);
·  break;
·  
·  default:
·  hang();
·  }



env_relocate();
drv_vfd_init();
serial_initialize();
 gd->bd->bi_ip_addr=getenv_IPaddr("ipaddr");    //IP地址
enable_interrupts();




·  if((s=getenv("loadaddr"))!=NULL) {
·  load_addr = simple_strtoul (s, NULL,16); /*内核加载地址*/
·  }

eth_initialize(gd->bd);
//初始化网卡,这之前,全局变量区已经从保存好了ip地址和mac地址

#ifdef CONFIG_PRODUCT_WITH_BOOT
	fastapp_entry(0, NULL);
#endif


show_boot_env();

·   for (;;) {
·  main_loop   ();     /*进入main_loop()函数准备启动内核*/
·  }


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



·  static void  startmce_before_boot_kernel()
·  {
· 
· size=MCU_CODE_MAXSIZE;
· dwPtr= (unsigned int*)(0xf8400000);
·  for(i=0;i<(size>>2);i++)
·  {
·  *(volatile unsigned int *)(dwPtr + I) = lu32vC51Code2[i];   
                   /*加载单片机程序*/
·  }
·  
    ...
·  //Set GPIO port param
·  *(volatile unsigned int *)(dwPtr+24) = gpio_port;

· ...
·  //单片机启动  CPU休眠
·  ret= readl(0xf840f000);        8051 Local RAM
·  ret |=0x1;
·  writel(ret,0xf840f000);
·  }



·  static void standby_before_get_kernel (unsigned set_code_only)
·  {
· 
·  
·  for(i = 0; I < (size >> 2);i++)
·  {
·  *(volatile unsigned int *)(dwPtr + I) = lu32vC51Code[i];
                       /*加载单片机程序*/
·  }
·  
·  
·  //设置IR的参数
·  *(volatile unsigned int *)(dwPtr+10) = irtype;
·  *(volatile unsigned int *)(dwPtr+11) = irpmocnum;
· for(i = 0;i < irpmocnum; i++)
· {
·  *(volatile unsigned int *)(dwPtr+12 + 2*i) = irVallow[i];
·  *(volatile unsigned int *)(dwPtr+13 + 2*i) = irValhigh[i];
·  }
·  //GPIO 参数
·  *(volatile unsigned int *)(dwPtr+24) = gpio_port;



· if (set_code_only)
·  {
·  printf("C51: code seted, go on booting ...\n");
· }
·  else
·  {
·  printf("C51:Cortex-A9 is sleeping here.\n");
·  
·  //使能8051
·  ret=readl(0xf840f000);
·  ret|=0x1;
·  writel(ret,0xf840f000);
·  for  (;;);    //不会执行
·     }
·  }



//product/main.c
int fastapp_entry(int argc, char *argv[])
{
 #ifdef HI_ANDROID_BOOT_SUPPORT
    Android_Main();               //环境参数设置
#endif

#ifndef HI_ADVCA_SUPPORT
#ifdef HI_LOADER_SUPPORT
    Loader_Main();
#else
    HI_INFO_PRINT(HI_ID_SYS, "not support hisi loader!\n");
#endif
#endif

#ifdef HI_ADVCA_SUPPORT
	c51_loadCode();
#endif	

    return 0;
}


你可能感兴趣的:(UBoot)