使用 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 補齊導致的, 趕緊把內容補上, 就可以結案了.