目录
一、main_loop函数
二、去掉多余if判断函数
三、autoboot_command
3.1、abortboot
3.2、run_command_list
四、cli_loop
位置:u-boot-2022.01/common/main.c 40行
void main_loop(void)
{
const char *s;
bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
if (IS_ENABLED(CONFIG_VERSION_VARIABLE))
env_set("ver", version_string); /* set version variable */
cli_init();
if (IS_ENABLED(CONFIG_USE_PREBOOT))
run_preboot_environment_command();
if (IS_ENABLED(CONFIG_UPDATE_TFTP))
update_tftp(0UL, NULL, NULL);
if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))
efi_launch_capsules();
s = bootdelay_process();
if (cli_process_fdt(&s))
cli_secure_boot_cmd(s);
autoboot_command(s);
cli_loop();
panic("No CLI available");
void main_loop(void)
{
const char *s;
bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); //打印出启动进度
cli_init(); //命令初始化有关,初始化 hush shell 相关的变量
run_preboot_environment_command(); //获取环境变量 perboot 的内容
s = bootdelay_process(); //此函数会读取环境变量 bootdelay 和 bootcmd 的内容
autoboot_command(s); //检查倒计时是否结束
cli_loop(); //命令行处理函数
panic("No CLI available");
}
void autoboot_command(const char *s)
{
debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "");
if (s && (stored_bootdelay == -2 ||
(stored_bootdelay != -1 && !abortboot(stored_bootdelay)))) { //函数 abortboot 返回值为 0。键盘按下导致为一
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);
}
}
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;
}
static int abortboot_single_key(int bootdelay)
{
int abort = 0;
unsigned long ts;
printf("Hit any key to stop autoboot: %2d ", bootdelay);
/*
* Check if key already pressed 判断键盘是否有按下
*/
if (tstc()) { /* we got a key press */
getchar(); /* 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 (tstc()) { /* we got a key press */
int key;
//倒计时赋值0,返回赋值1
abort = 1; /* don't auto boot */
bootdelay = 0; /* no more delay */
key = getchar();/* consume input */
if (IS_ENABLED(CONFIG_AUTOBOOT_USE_MENUKEY))
menukey = key;
break;
}
udelay(10000);
} while (!abort && get_timer(ts) < 1000);
printf("\b\b\b%2d ", bootdelay);// \b退格
}
putc('\n');
return abort;
}
此函数会执行参数 s 指定的一系列命令,也就是环境变量 bootcmd 的命令
启动内核
命令行处理函数
void cli_loop(void)
{
bootstage_mark(BOOTSTAGE_ID_ENTER_CLI_LOOP);
parse_file_outer();
/* This point is never reached */
for (;;);
}
//位置:common/cli_hush.c
int parse_file_outer(void)
{
int rcode;
struct in_str input;
setup_file_in_str(&input); //初始化变量 input 的成员变量
rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON); //hush shell 的命令解释器
return rcode;
}
static int parse_stream_outer(struct in_str *inp, int flag)
{
struct p_context ctx;
o_string temp=NULL_O_STRING;
int rcode;
int code = 1;
do {
ctx.type = flag;
initialize_context(&ctx);
update_ifs_map();
if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset((uchar *)";$&|", 0);
inp->promptmode=1;
rcode = parse_stream(&temp, &ctx, inp,
flag & FLAG_CONT_ON_NEWLINE ? -1 : '\n'); //命令解析
if (rcode == 1) flag_repeat = 0;
if (rcode != 1 && ctx.old_flag != 0) {
syntax();
flag_repeat = 0;
}
if (rcode != 1 && ctx.old_flag == 0) {
done_word(&temp, &ctx);
done_pipe(&ctx,PIPE_SEQ);
code = run_list(ctx.list_head); //执行命令
if (code == -2) { /* exit */
b_free(&temp);
code = 0;
/* XXX hackish way to not allow exit from main loop */
if (inp->peek == file_peek) {
printf("exit not allowed from main input shell.\n");
continue;
}
break;
}
if (code == -1)
flag_repeat = 0;
} else {
if (ctx.old_flag != 0) {
free(ctx.stack);
b_reset(&temp);
}
if (inp->__promptme == 0) printf("\n");
inp->__promptme = 1;
temp.nonnull = 0;
temp.quote = 0;
inp->p = NULL;
free_pipe_list(ctx.list_head,0);
}
b_free(&temp);
/* loop on syntax errors, return on EOF */
} while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP) &&
(inp->peek != static_peek || b_peek(inp)));
return (code != 0) ? 1 : 0;
}