现在的位置: 首页 > 综合 > 正文

U-boot源码简要分析(二)

2012年06月11日 ⁄ 综合 ⁄ 共 5156字 ⁄ 字号 评论关闭

现在我们再来看看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_len


u-boot

代码长度。

初始化循环

init_sequence


是一个初始化函数集的函数指针数组

(后面讲解)

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

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



 

 

初始化堆空间,清零。

 

 

初始化

Nor Flash


相关参数,并显示其大小。

 

 

 

 

 

初始化
VFD

存储区(
LCD

显示相关)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

初始化
LCD

显存

 

 

 

 

 

 

 

 

 

 

 

初始化

Nand Flash


控制器,并显示其容量大小

 

 

 

初始化
OneNand

 

 

 

 

初始化
DataFlash

 

初始化环境变量,如果认为没有找到存储其中的,就用默认值并打印:

“*** Warning - bad CRC, using default environment”


。这是我们常看到的。

 

 

初始化

VFD


LCD

显示相关)

 

 

 

 

初始化串口。

 

 

从环境变量里获取
IP

地址

 

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

、键盘等等

 

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

跳转表是一个函数指针数组,定义了
u-boot

中基本的常用的函数库,
gd->jt

是这个函数指针数组的首指针。

 

初始化
API

,用于为
U-boot

编写的


应用程序

 

初始化
console

,平台无关,不一定是串口哦,如果把标准输出设为
vga

,字符会显示在
LCD

上。

 

 

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

 

 

 

 

 

 

 

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

 

 

 

 

 

TI

芯片中的内置
MAC

初始化(平台相关)

 

 

 

 

 

 

 

 

 

 

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

 

 

 

 

 

 

抱歉!评论已关闭.