u-boot学习笔记系列(17) -- autoboot

https://github.com/wdfk-prog/U-boot-Study

autoboot.c

autoboot_command 自动启动命令

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

    if (s //有bootcmd
    && (stored_bootdelay == -2 ||
        //有延迟时间,且没有按键中断
         (stored_bootdelay != -1 && !abortboot(stored_bootdelay)))) {
        bool lock;
        int prev;

        lock = autoboot_keyed() &&
            !IS_ENABLED(CONFIG_AUTOBOOT_KEYED_CTRLC);
        if (lock)
            prev = disable_ctrlc(1); /* disable Ctrl-C checking */

        run_command_list(s, -1, 0);

        if (lock)
            disable_ctrlc(prev);    /* restore Ctrl-C checking */
    }

    if (IS_ENABLED(CONFIG_AUTOBOOT_USE_MENUKEY) &&
        menukey == AUTOBOOT_MENUKEY) {
        s = env_get("menucmd");
        if (s)
            run_command_list(s, -1, 0);
    }
}

abortboot 检查是否有按键中断

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

    if (bootdelay >= 0) {
        if (autoboot_keyed())
            abort = abortboot_key_sequence(bootdelay);
        else
            abort = abortboot_single_key(bootdelay);
    }

    if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && abort)
        gd->flags &= ~GD_FLG_SILENT;

    return abort;
}

passwd_abort_key

  • 输入bootdelaykey或者bootstopkey中的任意一个按键,则返回1;终止自动启动
  • bootdelaykey的匹配字符串为env中的bootdelaykey的值,如果没有配置,则使用CONFIG_AUTOBOOT_DELAY_STR的值
  • bootstopkey的匹配字符串为env中的bootstopkey的值,如果没有配置,则使用CONFIG_AUTOBOOT_STOP_STR的值
static int passwd_abort_key(uint64_t etime)
{
    int abort = 0;
    struct {
        char *str;
        u_int len;
        int retry;
    }
    delaykey[] = {
        { .str = env_get("bootdelaykey"),  .retry = 1 },
        { .str = env_get("bootstopkey"),   .retry = 0 },
    };

    char presskey[DELAY_STOP_STR_MAX_LENGTH];
    //需要匹配的输入字符串,env中没有配置则宏定义的字符串
#  ifdef CONFIG_AUTOBOOT_DELAY_STR  //默认为"",即任意都不匹配
    if (delaykey[0].str == NULL)
        delaykey[0].str = CONFIG_AUTOBOOT_DELAY_STR;
#  endif
#  ifdef CONFIG_AUTOBOOT_STOP_STR   //默认为" ",即输入空格终止
    if (delaykey[1].str == NULL)
        delaykey[1].str = CONFIG_AUTOBOOT_STOP_STR;
#  endif

    do {
        //检查是否有按键输入
        if (tstc()) {
        }
        //获取按键输入并进行匹配
        for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i++) {
            if (delaykey[i].len > 0 &&
                presskey_len >= delaykey[i].len &&
                memcmp(presskey + presskey_len -
                    delaykey[i].len, delaykey[i].str,
                    delaykey[i].len) == 0) {
                    debug_bootkeys("got %skey\n",
                        delaykey[i].retry ? "delay" :
                        "stop");

                /* don't retry auto boot */
                //如果是STOP按键,则不再重试
                if (!delaykey[i].retry)
                    bootretry_dont_retry(); //重试时间设置为-1,不在重试
                abort = 1;
            }
        }
        udelay(10000);
    } while (!abort && get_ticks() <= etime);

    return abort;
}

abortboot_single_key

  • 获取任意输入,就终止

bootdelay_process

  • 获取bootdelay的值,如果没有配置,则使用CONFIG_BOOTDELAY的值
const char *bootdelay_process(void)
{
	char *s;
	int bootdelay;

	bootcount_inc();

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

	/*
	 * Does it really make sense that the devicetree overrides the user
	 * setting? It is possibly helpful for security since the device tree
	 * may be signed whereas the environment is often loaded from storage.
	 */
	if (IS_ENABLED(CONFIG_OF_CONTROL))
		bootdelay = ofnode_conf_read_int("bootdelay", bootdelay);

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

	if (IS_ENABLED(CONFIG_AUTOBOOT_MENU_SHOW))
		bootdelay = menu_show(bootdelay);
	bootretry_init_cmd_timeout();

#ifdef CONFIG_POST
	if (gd->flags & GD_FLG_POSTFAIL) {
		s = env_get("failbootcmd");
	} else
#endif /* CONFIG_POST */
	if (bootcount_error())
		s = env_get("altbootcmd");
	else
		s = env_get("bootcmd");

	if (IS_ENABLED(CONFIG_OF_CONTROL))
		process_fdt_options();
	stored_bootdelay = bootdelay;

	return s;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值