1. 程式人生 > >uboot啟動流程之進uboot命令列和啟動核心

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,再後面就不說了,網路上搜索一下一大把。