uboot啟動流程之進uboot命令列和啟動核心
1.上電進board_init_r-->init_sequence_r-->run_main_loop
-->main_loop-->bootdelay_process-->autoboot_command主要就是這麼個流程
2.具體怎麼決定是進命令列還是啟動kernel是在autoboot_command決定的
void autoboot_command(const char *s) { debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) int prev = disable_ctrlc(1); /* disable Control C checking */ #endif
run_command_list(s, -1, 0);
#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) disable_ctrlc(prev); /* restore Control C checking */ #endif }
#ifdef CONFIG_MENUKEY if (menukey == CONFIG_MENUKEY) { s = getenv("menucmd"); if (s) run_command_list(s, -1, 0); } #endif /* CONFIG_MENUKEY */ } 3. 進入abortboot-->abortboot_normal
static int abortboot_normal(int bootdelay) {
...
#if defined CONFIG_ZERO_BOOTDELAY_CHECK /* * Check if key already pressed * Don't check if bootdelay < 0 */ if (bootdelay >= 0) { if (tstc()) { /* we got a key press */ key = getc(); /* consume input */ puts("\b\b\b 0"); switch (key) { case 0x03: /* ^C - Ctrl+C */ case 0x0d: /* Enter */ case 0x20: /* Space */ //only "enter" key can triger abort abort = 1; /* don't auto boot */ } } } #endif
...
return abort;
}
這裡可以看到鍵盤按Ctrl+C、enter、或者Space將abort置1,函式結尾返回
4. 回到autoboot_command可以看到如果abortboot_normal返回1則autoboot_command執行完成回到main_loop繼續跑到cli_loop-->cli_simple_loop進入並停在命令列模式。
5. 上面是命令列模式,下面說上電啟動kernel
同樣在autoboot_command-->abortboot返回0,autoboot_command裡呼叫run_command_list執行命令bootcmd啟動kernel
具體如下board相關配置檔案會參考如下配置bootcmd
#define CONFIG_BOOTCOMMAND "run storeboot"
...
"storeboot="\ "if imgread kernel boot ${loadaddr}; then "\ "bootm ${loadaddr}; "\ "fi; "\ "run update; "\ "\0"\
在env_default.h裡
const uchar default_environment[] = {
...
#ifdef CONFIG_BOOTCOMMAND "bootcmd=" CONFIG_BOOTCOMMAND "\0" #endif
...
}
main_loop函式裡會在呼叫autoboot_command(s);執行啟動linuxkernel之前呼叫s = bootdelay_process();獲取bootcmd命令。
後面就是bootm命令呼叫do_bootm-->do_bootm_states-->boot_fn(bootm_os_get_boot_func)-->
boot_os[os]-->do_bootm_linux,再後面就不說了,網路上搜索一下一大把。