Chinaunix首页 | 论坛 | 博客
  • 博客访问: 57509
  • 博文数量: 9
  • 博客积分: 227
  • 博客等级: 二等列兵
  • 技术积分: 110
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-19 02:11
文章分类
文章存档

2012年(9)

分类: LINUX

2012-04-19 07:52:15

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

gd_t bd_t 这两个数据结 构比较重要,建议大家看 看。 分配一个存储全局数据的区域,地 址给指针 gd

全局数据的区清零

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

gd->flags 赋值,表示已经重定向

(在内存中)

monitor_flash_len u-boot 代码长 度。

初始化循环:

init_sequence 是一个初始化函数 集的函数指针数组(后面讲解) 如果有任何一个函数失败就进入死 循环。 这个始化函数集比较重要, 建议大家认真跟踪一下。

初始化堆空间,清零。

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

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

关)


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

初始化 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 上。

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


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

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

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

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

获取 bootfile 参数

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

SD /MMC 控制器初始化

MII 相关初始化

网卡初始化

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

bootcmd

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


main_loop ();

}

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

 

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