【TINY4412】U-BOOT移植笔记:(4)U-BOOT执行流程

【TINY4412】U-BOOT移植笔记:(4)U-BOOT执行流程

宿主机 : 虚拟机 Ubuntu 16.04 LTS / X64
目标板[底板]: Tiny4412SDK - 1506
目标板[核心板]: Tiny4412 - 1412
U-BOOT版本: 2017.03
交叉编译器: gcc-arm-none-eabi-5_4-2016q3
日期: 2017-4-22 12:01:27
作者: SY

SPL执行流程

root@ubuntu:/opt/u-boot-2017.03# more board/samsung/common/exynos-uboot-spl.lds
ENTRY(_start)

SECTIONS
{
.text :
{
__start = .;
*(.vectors)
arch/arm/cpu/armv7/start.o (.text*)
*(.text*)
} >.sram
. = ALIGN(4);
}
1. 根据ENTRY(_start),可知先执行 __start
2. 找到 arch/arm/lib/vectors.S 
/*
*************************************************************************
*
* Symbol _start is referenced elsewhere, so make it global
*
*************************************************************************
*/

.globl _start

可知这个符号是一个全局符号。
_start:

#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
.word   CONFIG_SYS_DV_NOR_BOOT_CFG
#endif

b       reset
然后执行 reset
3. 找到 root@ubuntu:/opt/u-boot-2017.03# more arch/arm/cpu/armv7/start.S
4. 因为配置了CONFIG_SKIP_LOWLEVEL_INIT,
跳过 bl      cpu_init_cp15,
跳过 bl      cpu_init_crit,
执行 bl _main
5. root@ubuntu:/opt/u-boot-2017.03# more arch/arm/lib/crt0.S
6. 执行 bl      board_init_f
7. 找到 root@ubuntu:/opt/u-boot-2017.03# more arch/arm/mach-exynos/spl_boot.c 
执行 void board_init_f(unsigned long bootflag); 
执行 void do_lowlevel_init();
8. 进入 root@ubuntu:/opt/u-boot-2017.03# more arch/arm/mach-exynos/lowlevel_init.c
9. 执行 system_clock_init(); 初始化系统时钟
10. 执行 exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);
debug_uart_init(); 初始化串口0 
11. 执行 mem_ctrl_init(); 初始化SDRAM,为了下一步加载U-BOOT.bin做准备
12. 执行 tzpc_init(); 配置 TrustZone Protection Controller
13. 执行 copy_uboot_to_ram(), 将u-boo.bin从启动媒介拷贝到SDRAM的
CONFIG_SYS_TEXT_BASE 位置。
14. 跳转到u-boot执行: 
/* Jump to U-Boot image */
uboot = (void *)CONFIG_SYS_TEXT_BASE;
(*uboot)();

U-BOOT 执行流程

1. 前面的步骤和SPL中执行的都一样。
2. 执行到 bl   board_init_f时,查看文件`arch\arm\mach-exynos\Makefile`

ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_EXYNOS5)  += clock_init_exynos5.o
obj-$(CONFIG_EXYNOS5)  += dmc_common.o dmc_init_ddr3.o
obj-$(CONFIG_EXYNOS4210)+= dmc_init_exynos4.o clock_init_exynos4.o
obj-$(CONFIG_EXYNOS4412)+= dmc_init_exynos4412.o clock_init_exynos4412.o
obj-y   += spl_boot.o tzpc.o
obj-y   += lowlevel_init.o
endif

当执行U-BOOT时,这些文件都不会被编译。因此,执行到`common\board_f.c`时,
会跳转到void board_init_f(ulong boot_flags)函数。
3. 紧接着:
if (initcall_run_list(init_sequence_f))
hang();
init_sequence_f是一个函数指针数组,initcall_run_list()函数会依次遍历
数组中的每一个元素,并执行。正常情况下不会执行到hang(),而数组的最后一个
元素为 NULL,作为退出条件:
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr);
4. b    relocate_code
5. bl   relocate_vectors
6. bl coloured_LED_init
7. bl red_led_on
8. ldr  pc, =board_init_r 执行`common\Board_r.c`中的
void board_init_r(gd_t *new_gd, ulong dest_addr);
9. 执行:
if (initcall_run_list(init_sequence_r))
hang();
init_sequence_r是一个函数指针数组,最后一个成员是 run_main_loop()
10. 执行 void main_loop(void);
11. 执行 void cli_loop(void);
12. 执行 cli_simple_loop();

常见问题

  • 死机
    • :使用 sd_fuse/tiny4412/sd_fusing.sh生成的bl2.bin文件,烧录到开发板,经过放置小灯测试,在执行 bl board_init_f_alloc_reserve 时,会出现死机情况?
    • 原因:bl2.bin使用u-boot根目录的u-boot.bin制作而成,而在BL2阶段应该执行的文件是./spl/tiny4412-spl.bin,该文件使用./spl/u-boot-spl.bin制作而成。见:./script/Makefile.spl中的 259 $(obj)/$(BOARD)-spl.bin: $(obj)/u-boot-spl.bin
    • 解决:修改 ./sd_fuse/tiny4412/sd_fusing.sh,
      C
      #<BL2 fusing>
      echo "---------------------------------------"
      echo "BL2 fusing"
      #dd iflag=dsync oflag=dsync if=./bl2.bin of=$1 seek=$bl2_position
      dd iflag=dsync oflag=dsync if=../../spl/tiny4412-spl.bin of=$1
      seek=$bl2_position
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值