2021/01/15

U-boot entry point

使用 Qualcomm 的 ipq 平台開發產品, 一個不小心遇到了 uboot 完全不會動的狀況, 連一開始顯示版本資訊的訊息都沒出現, 這下糟糕了, 根本就不能用 printf 去看他停在哪裡!

只好從uboot的進入點開始看了. 由於平台使用的是 armv7 的架構, 所以從 (uboot)/arch/arm/cpu/armv7/start.S 開始看. 雖然是組合語言, 幸好只是要看 b, bl, blx, bx 這一系列的分支指令, 而且很幸運的是整個 start.S 只用到 bl 這個.

ARM branch operation

那就一個一個的來找看看 c 的實作:

save_boot_params

void save_boot_params_default(u32 r0, u32 r1, u32 r2, u32 r3) { } void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) __attribute__((weak, alias("save_boot_params_default")));

空空的.


cpu_init_cp15

cpu_init_crit

這兩個都在 start.S 後面用組合實作


board_init_f

實作在 uboot/arch/arm/lib/board.c

init_fnc_t *init_sequence[] = {
	arch_cpu_init,		/* basic arch cpu dependent setup */

#if defined(CONFIG_BOARD_EARLY_INIT_F)
	board_early_init_f,
#endif
#ifdef CONFIG_OF_CONTROL
	fdtdec_check_fdt,
#endif
	timer_init,		/* initialize timer */
#ifdef CONFIG_FSL_ESDHC
	get_clocks,
#endif
	env_init,		/* initialize environment */
	init_baudrate,		/* initialze baudrate settings */
	serial_init,		/* serial communications setup */
	console_init_f,		/* stage 1 init of console */
	display_banner,		/* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
	print_cpuinfo,		/* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
	checkboard,		/* display board info */
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
	init_func_i2c,
#endif
	dram_init,		/* configure available RAM banks */
	NULL,
};

void board_init_f(ulong bootflag)
{
        ... ...
	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
		if ((*init_fnc_ptr)() != 0) {
			hang ();
		}
	}
	... ...
}

這裡會逐一呼叫 *init_sequence[] 裡面定義的 function, 如果有哪個 function 傳回不是 0, 就吊起.

追了這些 function, 終於發現是新增 machid, 還沒把相關的 board_parameter 補齊導致的, 趕緊把內容補上, 就可以結案了.