自学内容网 自学内容网

uboot剖析之命令行延时

configs/rk3506_defconfig文件中可以配置启动延时选项

CONFIG_BOOTDELAY=3

main_loop:bootdelay_process处理delay延时值解析,按键捕获由autoboot_command负责

void main_loop(void)
{
        const char *s;

        bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");

#ifdef CONFIG_VERSION_VARIABLE
        env_set("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:要么从环境变量bootdelay里边获取,要么就从CONFIG_BOOTDELAY里边获取,最后更新stored_bootdelay

const char *bootdelay_process(void)
{
        char *s;
        int bootdelay;
#ifdef CONFIG_BOOTCOUNT_LIMIT
        unsigned long bootcount = 0;
        unsigned long bootlimit = 0;
#endif /* CONFIG_BOOTCOUNT_LIMIT */

#ifdef CONFIG_BOOTCOUNT_LIMIT
        bootcount = bootcount_load();
        bootcount++;
        bootcount_store(bootcount);
        env_set_ulong("bootcount", bootcount);
        bootlimit = env_get_ulong("bootlimit", 10, 0);
#endif /* CONFIG_BOOTCOUNT_LIMIT */

        s = env_get("bootdelay");
        bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;

#ifdef CONFIG_OF_CONTROL
        bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay",
                        bootdelay);
#endif

        debug("### main_loop entered: bootdelay=%d\n\n", bootdelay);

#if defined(CONFIG_MENU_SHOW)
        bootdelay = menu_show(bootdelay);
#endif
        bootretry_init_cmd_timeout();

#ifdef CONFIG_POST
        if (gd->flags & GD_FLG_POSTFAIL) {
                s = env_get("failbootcmd");
        } else
#endif /* CONFIG_POST */
#ifdef CONFIG_BOOTCOUNT_LIMIT
        if (bootlimit && (bootcount > bootlimit)) {
                printf("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
                       (unsigned)bootlimit);
                s = env_get("altbootcmd");
        } else
#endif /* CONFIG_BOOTCOUNT_LIMIT */
                s = env_get("bootcmd");

        process_fdt_options(gd->fdt_blob);
        stored_bootdelay = bootdelay;

        return s;
}

autoboot_command:在执行启动命令run_command_list前先检查stored_bootdelay

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);
                autoboot_command_fail_handle();

#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 = env_get("menucmd");
                if (s)
                        run_command_list(s, -1, 0);
        }
#endif /* CONFIG_MENUKEY */
}

abortboot:真正的功能实现在__abortboot

static int abortboot(int bootdelay)
{
        int abort = 0;

        if (bootdelay >= 0)
                abort = __abortboot(bootdelay);

#ifdef CONFIG_SILENT_CONSOLE
        if (abort)
                gd->flags &= ~GD_FLG_SILENT;
#endif

        return abort;
}

__abortboot:bootdelay延时计数 + 等待按键ctrl+c输入

static int __abortboot(int bootdelay)
{
        int abort = 0;
        unsigned long ts;

#ifdef CONFIG_MENUPROMPT
        printf(CONFIG_MENUPROMPT);
#else
        printf("Hit key to stop autoboot('CTRL+C'): %2d ", bootdelay);
#endif

#ifdef CONFIG_ARCH_ROCKCHIP
        if (!IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI) && ctrlc()) {        /* we press ctrl+c ? */
#else
        /*
         * Check if key already pressed
         */
        if (tstc()) {        /* we got a key press        */
#endif
                (void) getc();  /* consume input        */
                puts("\b\b\b 0");
                abort = 1;        /* don't auto boot        */
        }

        while ((bootdelay > 0) && (!abort)) {
                --bootdelay;
                /* delay 1000 ms */
                ts = get_timer(0);
                do {
                        if (ctrlc()) {        /* we got a ctrl+c key press        */
                                abort  = 1;        /* don't auto boot        */
                                bootdelay = 0;        /* no more delay        */
# ifdef CONFIG_MENUKEY
                                menukey = 0x03;        /* ctrl+c key code */
# endif
                                break;
                        }
                        udelay(10000);
                } while (!abort && get_timer(ts) < 1000);

                printf("\b\b\b%2d ", bootdelay);
        }

        putc('\n');

        return abort;
}

原文地址:https://blog.csdn.net/HeavenMo/article/details/145279962

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!