上篇博客:http://www.cnblogs.com/yeqluofwupheng/p/7347925.html
讲到uboot-spl的工作流程,接下来简述一下uboot.bin的工作流程,这对应BL2的流程。
BL2的主要文件和任务流程如下:
arch/arm/cpu/armv7/start.S
1. 设置CPU为SVC模式
2. 关闭MMU
3. 关闭Cache
4. 跳转到lowlevel_init.S low_level_init
board/samsung/origen/lowlevel_init.S
5. 初始化时钟
6. 初始化内存
7. 初始化串口
8. 关闭看门狗
9. 跳转到crt0.S _main
arch/arm/lib/crt0.S
10. 设置栈
11. 初始化C运行环境
12. 调用board_init_f()
arch/arm/lib/board.c
13. board_init_f对全局信息GD结构体进行填充
arch/arm/lib/crt0.S
14. 代码重定位------------BL2的最后的工作, 执行完就进入DRAM执行BL2
1.首先从board_init_f函数开始,它是定义在/u-boot/arch/arm/lib/board.c文件中。
它的作用是初始化开发板。需要注意的是,此时程序是在flash中运行的。
1 void board_init_f(ulong bootflag) 2 { 3 bd_t *bd; 4 init_fnc_t **init_fnc_ptr; 5 gd_t *id; 6 ulong addr, addr_sp; 7 8 #if defined(CONFIG_ARCH_SUN8IW6P1) || defined(CONFIG_ARCH_SUN9IW1P1) 9 memset((void*)0x00000000, 0, 4*1024); 10 #endif 11 /* Pointer is writable since we allocated a register for it */ 12 gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07); 13 /* compiler optimization barrier needed for GCC >= 3.4 */ 14 __asm__ __volatile__("": : :"memory"); 15 16 memset((void *)gd, 0, sizeof(gd_t)); 17 gd->mon_len = _bss_end_ofs + sizeof(struct spare_boot_head_t); 18 gd->debug_mode = 1;
gd是一个保存在ARM的r8寄存器中的gd_t结构体的指针,该结构体包括了u-boot中所有重要的全局变量,它是在arch/arm/include/asm目录下的global_data.h文件内被定义的。上述代码的作用是为gd分配地址,并清零,最后得到整个u-boot的长度。gd_t结构体的定义如下:
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_FSL_ESDHC unsigned long sdhc_clk; #endif #ifdef CONFIG_AT91FAMILY /* "static data" needed by at91's clock.c */ unsigned long cpu_clk_rate_hz; unsigned long main_clk_rate_hz; unsigned long mck_rate_hz; unsigned long plla_rate_hz; unsigned long pllb_rate_hz; unsigned long at91_pllb_usb_init; #endif #ifdef CONFIG_ARM /* "static data" needed by most of timer.c on ARM platforms */ unsigned long timer_rate_hz; unsigned long tbl; unsigned long tbu; unsigned long long timer_reset_value; unsigned long lastinc; #endif #ifdef CONFIG_IXP425 unsigned long timestamp; #endif unsigned long relocaddr; /* Start address of U-Boot in RAM */ phys_size_t ram_size; /* RAM size */ unsigned long ram_size_mb; /* RAM size MB*/ unsigned long mon_len; /* monitor len */ unsigned long irq_sp; /* irq stack pointer */ unsigned long start_addr_sp; /* start_addr_stackpointer */ unsigned long reloc_off; #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) unsigned long tlb_addr; #endif #if defined(CONFIG_ALLWINNER) int uart_console; int boot_card_num; unsigned int layer_para; unsigned int layer_hd; int key_pressd_value; int axp_power_soft_id; int power_step_level; int pmu_suspend_chgcur; int pmu_runtime_chgcur; int limit_vol; int limit_cur; int limit_pcvol; int limit_pccur; int power_main_id; int power_slave_id; char *script_mod_buf; int script_main_key_count; int force_shell; uint malloc_noncache_start; int lockflag; uint chargemode; uint force_download_uboot; int securemode; uint vbus_status; //0: 未知;1:存在;2:不存在 uint debug_mode; #endif void **jt; /* jump table */ char env_buf[32]; /* buffer for getenv() before reloc. */ } gd_t;