typedef struct global_data { bd_t *bd; unsigned long flags; unsigned long baudrate; unsigned long have_console; /* serial_init() was called */ unsigned long env_addr; /* Address of Environment struct */ unsigned long env_valid; /* Checksum of Environment valid? */ unsigned long fb_base; /* base address of frame buffer */ #ifdef CONFIG_VFD unsigned char vfd_type; /* display type */ #endif #ifdef CONFIG_FSL_ESDHC unsigned long sdhc_clk; #endif #if 0 unsigned long cpu_clk; /* CPU clock in Hz! */ unsigned long bus_clk; phys_size_t ram_size; /* RAM size */ unsigned long reset_status; /* reset status register at boot */ #endif void **jt; /* jump table */ } gd_t; |
(1) 它的内存位置在堆的下面。
(2) 它在board.c中的start_armboot中初始化。
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; |
(3)
1) 函数Start_armboot做一些初始化工作,最后进入main_loop等待用户输入命令。
2) 初始化工作有:
3) gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
定位gd到堆地址的下面。
4) monitor_flash_len = _bss_start - _armboot_start;
monitor_flash_len表示u-boot映像的大小。
_bss_start在Start.S中定义:
.globl _bss_start _bss_start: .word __bss_start //这个变量在u-boot.lds中定义 |
5) 下面的代码执行一系列的初始化,如果初始化失败,则进入hang,报错进入死循环:
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } } |
6) 下面调用mem_malloc_init初始化堆,此函数只是简单地将起始地址和大小赋给变量。
7) 由于使用NandFlash,所以执行代码:
#if defined(CONFIG_CMD_NAND) puts ("NAND: "); nand_init(); /* go init the NAND */ #endif |
nand_init函数在/driver/mtd/nand/Nand.c中。
8) AT91F_DataflashInit
#ifdef CONFIG_HAS_DATAFLASH AT91F_DataflashInit(); dataflash_print_info(); #endif |
9) env_relocate ();初始化环境变量。
10)
/* IP Address */ 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 ();
/* Initialize from environment */ if ((s = getenv ("loadaddr")) != NULL) { load_addr = simple_strtoul (s, NULL, 16); }
puts ("Net: "); eth_initialize(gd->bd);
reset_phy();
… Main_loop(); …
|
at91sam9260ek的有效初始化列表如下:
init_fnc_t *init_sequence[] = { arch_cpu_init, //(arch/arm/cpu/arm926ejs/cpu.c中) board_init, /* basic board dependent setup */ timer_init, //(arch/arm/cpu/arm926ejs/Timer.c中) env_init, /* initialize environment */ init_baudrate, /* initialze baudrate settings */ serial_init, //driver/serial/Atmel_usart.c console_init_f, /* stage 1 init of console */ display_banner, /* say that we are here */ dram_init, /* configure available RAM banks */ display_dram_config, NULL, }; |
(1) arch_cpu_init
先调用at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);,再调用at91_clock_init(clock.c中)。
At91sam9260ek.h定义:
#define CONFIG_SYS_AT91_MAIN_CLOCK 18432000 /* 18.432 MHz crystal */ |
(2) board_init
初始化串口的PIO,串口的进一步初始化在serial_init中。
调用at91sam9260ek_macb_hw_init,这里应该是初始化MAC(待分析)。
(3) timer_init
初始化PIT,里面有个延时函数。
(4) env_init
env_init函数所在文件由配置决定。在common/Makefile中:
# environment COBJS-y += env_common.o COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o COBJS-$(CONFIG_ENV_IS_EMBEDDED) += env_embedded.o COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_embedded.o COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_embedded.o COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o COBJS-$(CONFIG_ENV_IS_IN_MG_DISK) += env_mgdisk.o COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o |
函数内的代码将环境变量置为缺省:
int env_init(void) { gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 1; } |
(5) init_baudrate
获取终端串口的波特率,先从环境变量读取,若不存在则置CONFIG_BAUDRATE定义的值。
(6) serial_init
终端输出串口的初始化。在Atmel_usart.c中还有终端输出的实现。
(7) console_init_f
(8) display_banner
打印“U-Boot 2010.06 (May 15 2011 - 22:15:58)”
(9) dram_init
设置ram的起始地址(0x20000000)和大小(64M)。
(10)display_dram_config
打印RAM的大小“RAM:64M”