Chinaunix首页 | 论坛 | 博客
  • 博客访问: 71656
  • 博文数量: 68
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-27 21:43
文章分类
文章存档

2014年(68)

我的朋友

分类: LINUX

2014-07-05 22:08:53

现在我们再来看看lib_arm/board.c中的第二阶段入口函数start_armboot :

void start_armboot (void)                     

{

       init_fnc_t **init_fnc_ptr;

       char *s;

#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));

       /* 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));

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

 

       gd->flags |= GD_FLG_RELOC;

 

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

              }

       }

 

       /* armboot_start is defined in the board-specific linker script */

       mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,

                     CONFIG_SYS_MALLOC_LEN);

 

#ifndef CONFIG_SYS_NO_FLASH

       /* configure available FLASH banks */

       display_flash_config (flash_init ());

#endif /* CONFIG_SYS_NO_FLASH */

 

#ifdef CONFIG_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

       /* 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 */

#endif

 

#if defined(CONFIG_CMD_ONENAND)

       onenand_init();

#endif

 

#ifdef CONFIG_HAS_DATAFLASH

       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");

 

       stdio_init ();    /* get the devices list going. */

 

       jumptable_init ();

 

#if defined(CONFIG_API)

       /* Initialize API */

       api_init ();

#endif

 

       console_init_r ();    /* fully init console as a device */

 

#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) {

              load_addr = simple_strtoul (s, NULL, 16);

       }

#if defined(CONFIG_CMD_NET)

       if ((s = getenv ("bootfile")) != NULL) {

              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 */

}

 

 

 

 

 

 

 

 

 

gd_t bd_t这两个数据结构比较重要,建议大家看看。

分配一个存储全局数据的区域,地址给指针 gd

 

 

全局数据的区清零

gd->bd(指针)赋值(在gd的前面)并清零

 

gd->flags 赋值,表示已经重定向(在内存中)

monitor_flash_lenu-boot代码长度。

初始化循环

init_sequence 是一个初始化函数集的函数指针数组(后面讲解)

如果有任何一个函数失败就进入死循环。

这个始化函数集比较重要,建议大家认真跟踪一下。

 

 

初始化堆空间,清零。

 

 

初始化Nor Flash相关参数,并显示其大小。

 

 

 

 

 

初始化VFD存储区(LCD显示相关)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

初始化LCD显存

 

 

 

 

 

  

 

 

 

 

初始化Nand Flash控制器,并显示其容量大小

 

 

 

初始化OneNand

 

 

 

 

初始化 DataFlash

 

初始化环境变量,如果认为没有找到存储其中的,就用默认值并打印:“*** Warning - bad CRC, using default environment”。这是我们常看到的。

 

 

初始化 VFDLCD显示相关)

 

 

 

 

初始化串口。

 

 

从环境变量里获取IP地址

 

初始化标准输入输出设备。比如:串口、LCD、键盘等等

 

初始化全局数据表中的跳转表gd->jt

跳转表是一个函数指针数组,定义了u-boot中基本的常用的函数库,gd->jt是这个函数指针数组的首指针。

 

初始化API,用于为U-boot编写的应用程序

 

初始化 console,平台无关,不一定是串口哦,如果把标准输出设为vga,字符会显示在LCD上。

 

 

平台相关的其他初始化,有的平台有

 

 

 

 

 

 

 

中断使能(一般不使用,很多平台此函数是空的)

 

 

 

 

 

TI芯片中的内置MAC初始化(平台相关)

 

 

 

 

 

 

 

 

 

 

一种网卡芯片初始化(平台相关)

 

 

 

 

 

 

 

 

 

  

 

 

 

 

获取 bootfile参数

 

 

 

 

 

一些板级初始化(有的板子有)

 

 

  

SD/MMC控制器初始化

 

 

 

 

MII相关初始化

 

  

 

网卡初始化

 

 

 

 

 

 

 

进入主循环,其中会读取bootdelaybootcmd

bootdelay时间内按下键进入命令行,否则执行bootcmd的命令。

标有红色的是比较重要的地方。

大致的U-boot启动流程就简单介绍到这。

阅读(285) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~