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

日志

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

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

3init_sequence数组


       U-Boot使用一个数组init_sequence来存储对于大多数开发板都要执行的初始化函数的函数指针。init_sequence数组中有较多的编译选项,去掉编译选项后init_sequence数组如下所示:


typedef int (init_fnc_t) (void);


 


init_fnc_t *init_sequence[] = {


       board_init,         /*开发板相关的配置--board/samsung/mini2440/mini2440.c */


       timer_init,            /* 时钟初始化-- cpu/arm920t/s3c24x0/timer.c */


       env_init,            /*初始化环境变量--common/env_flash.c common/env_nand.c*/


       init_baudrate,      /*初始化波特率-- lib_arm/board.c */


       serial_init,            /* 串口初始化-- drivers/serial/serial_s3c24x0.c */


       console_init_f,    /* 控制通讯台初始化阶段1-- common/console.c */


       display_banner,   /*打印U-Boot版本、编译的时间-- gedit lib_arm/board.c */


       dram_init,            /*配置可用的RAM-- board/samsung/mini2440/mini2440.c */


       display_dram_config,              /* 显示RAM大小-- lib_arm/board.c */


       NULL,


};


       其中的board_init函数在board/samsung/mini2440/mini2440.c中定义,该函数设置了MPLLCOMUPLLCON,以及一些GPIO寄存器的值,还设置了U-Boot机器码和内核启动参数地址


/* MINI2440开发板的机器码 */


gd->bd->bi_arch_number = MACH_TYPE_MINI2440;


 


/* 内核启动参数地址 */


gd->bd->bi_boot_params = 0x30000100;  


       其中的dram_init函数在board/samsung/mini2440/mini2440.c中定义如下:


int dram_init (void)


{


      /* 由于mini2440只有 */


      gd->bd->bi_dram[0].start = PHYS_SDRAM_1;


      gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;


 


      return 0;


}


mini2440使用232MBSDRAM组成了64MB的内存,接在存储控制器的BANK6,地址空间是0x30000000~0x34000000


include/configs/mini2440.hPHYS_SDRAM_1PHYS_SDRAM_1_SIZE 分别被定义为0x300000000x0400000064M)。


       分析完上述的数据结构,下面来分析start_armboot函数:


void start_armboot (void)


{


       init_fnc_t **init_fnc_ptr;


       char *s;


       … …


       /* 计算全局数据结构的地址gd */


       gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));


       … …


       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;


 


/* 逐个调用init_sequence数组中的初始化函数  */


       for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {


              if ((*init_fnc_ptr)() != 0) {


                     hang ();


              }


       }


 


/* armboot_start cpu/arm920t/start.S 中被初始化为u-boot.lds连接脚本中的_start */


       mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,


                     CONFIG_SYS_MALLOC_LEN);


 


/* NOR Flash初始化 */


#ifndef CONFIG_SYS_NO_FLASH


       /* configure available FLASH banks */


       display_flash_config (flash_init ());


#endif /* CONFIG_SYS_NO_FLASH */


 


       … …


/* NAND Flash 初始化*/


#if defined(CONFIG_CMD_NAND)


       puts ("NAND:  ");


       nand_init();         /* go init the NAND */


#endif


       … …


       /*配置环境变量,重新定位 */


       env_relocate ();


       … …


       /* 从环境变量中获取IP地址 */


       gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");


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


       jumptable_init ();


       … …


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


       … …


       /* enable exceptions */


       enable_interrupts ();


 


#ifdef CONFIG_USB_DEVICE


       usb_init_slave();


#endif


 


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


       … …


       /* 网卡初始化 */


#if defined(CONFIG_CMD_NET)


#if defined(CONFIG_NET_MULTI)


       puts ("Net:   ");


#endif


       eth_initialize(gd->bd);


… …


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


}


       main_loop函数在common/main.c中定义。一般情况下,进入main_loop函数若干秒内没有


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)