u-boot - environment - bootcmd

Overview

bootcmd是environment中重要的一个环境变量,u-boot的最后阶段会执行bootcmd定义的命令。

bootcmd通常就会包括load和boot命令(如bootz),即把kernel image & Flatten Device Tree加载到内存,然后执行内核内核。如此,完成u-boot到kernel的启动转换。

调用顺序

前面已经提到过,在u-boot的初始化阶段,会读取environment的值。而bootcmd的执行则在u-boot启动的最后一部分,即main_loop()。

main_loop() -> bootdelay_process() + autoboot_command() -> env "bootcmd"

main_loop()

main_loop()会等待获取用户的输入命令,或(超时后)获取环境变量中的bootcmd,之后调用autoboot_command()执行bootcmd命令序列。

// common/main.c:

/* We come here after U-Boot is initialised and ready to process commands */
void main_loop(void)
{
    const char *s;

    bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");

#ifdef CONFIG_VERSION_VARIABLE
    setenv("ver", version_string);  /* set version variable */
#endif /* CONFIG_VERSION_VARIABLE */

    cli_init();

    run_preboot_environment_command();

#if defined(CONFIG_UPDATE_TFTP)
    update_tftp(0UL, NULL, NULL);
#endif /* CONFIG_UPDATE_TFTP */

    s = bootdelay_process();
    if (cli_process_fdt(&s))
        cli_secure_boot_cmd(s);

    autoboot_command(s);

    cli_loop();
    panic("No CLI available");
}

bootdelay_process()

这里的正常流程会获取环境变量中bootcmd的值,并返回这个值。

// common/autoboot.c

const char *bootdelay_process(void)
{
    char *s;
    int bootdelay;

    // ...
    s = getenv("bootcmd");
    // ...

    return s;
}

autoboot_command()

执行命令列表,如load, bootz等,即将内核等映像文件加载到内容,然后跳转到内核的第一条指令处执行,从而启动内核代码。

// common/autoboot.c

void autoboot_command(const char *s)
{
    debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");

    // ...
    run_command_list(s, -1, 0);
    // ...
}

猜你喜欢

转载自blog.csdn.net/u013344915/article/details/77119905