debug ("### main_loop: bootcmd=/"%s/"/n", s ? s : "<UNDEFINED>");
if (bootdelay >= 0 && s && !abortboot (bootdelay)) {//如果延时大于等于零,并且没有在延时过程中接收到按键,则引导内核。abortboot函数的分析见下面。 run_command (s, 0); //运行引导内核的命令。这个命令是在配置头文件中定义的。run_command的分析在下面。 }
#endif /* CONFIG_BOOTDELAY */
for (;;) { len = readline (CONFIG_SYS_PROMPT); //CONFIG_SYS_PROMPT的意思是回显字符,一般是“>”。这是由配置头文件定义的
flag = 0; /* assume no special flags for now */ if (len > 0) strcpy (lastcommand, console_buffer); //保存输入的数据。 else if (len == 0) flag |= CMD_FLAG_REPEAT;//如果输入数据为零,则重复执行上次的命令,如果上次输入的是一个命令的话
if (strlen(cmd) >= CONFIG_SYS_CBSIZE) { //命令太长 puts ("## Command too long!/n"); return -1; }
strcpy (cmdbuf, cmd); //将命令拷贝到临时命令缓冲cmdbuf
/* Process separators and check for invalid * repeatable commands */ while (*str) { //str指向cmdbuf
/* * Find separator, or string end * Allow simple escape of ";" by writing "/;" */ for (inquotes = 0, sep = str; *sep; sep++) { //寻找分割符或者命令尾部。相邻的句子之间是用;隔开的。每次处理一句命令 if ((*sep=="/"") && (*(sep-1) != "//")) inquotes=!inquotes;
if (!inquotes && (*sep == ";") && /* separator */ ( sep != str) && /* past string start */ (*(sep-1) != "//")) /* and NOT escaped */ break; }
/* * Limit the token to data between separators */ token = str; //token指向命令的开头 if (*sep) { //如果是分隔符的话,将分隔符替换为空字符 str = sep + 1; /* start of command for next pass */str指向下一句的开头 *sep = "/0"; } else str = sep; /* no more commands for next pass */如果没有其它命令了,str指向命令尾部
/* find macros in this token and replace them */ process_macros (token, finaltoken); //将token指向的命令中的宏替换掉,如把$(kernelsize)替换成内核的大小
/* Extract arguments */ if ((argc = parse_line (finaltoken, argv)) == 0) {//将每一个参数用‘/0’隔开,argv中的每一个指针指向一个参数的起始地址。 返回值为参数的个数 rc = -1; /* no command at all */ continue; }
/* Look up command in command table */ if ((cmdtp = find_cmd(argv[0])) == NULL) { //第一个参数就是要运行的命令,首先在命令表中找到它的命令结构体的指针 printf ("Unknown command "%s" - try "help"/n", argv[0]); rc = -1; /* give up after bad command */ continue; }
/* found - check max args */ if (argc > cmdtp->maxargs) { //检查参数个数是否过多 cmd_usage(cmdtp); rc = -1; continue; }
/* OK - call function to do the command */ if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {//调用命令执行函数。这是最重要的一步。 rc = -1; }
/* Did the user stop this? */ if (had_ctrlc ()) //检查是否有ctrl+c按键按下,如果有,结束当前命令。本函数并没有从中断接收字符,接收ctrl+c的是一些执行命令的函数。 return -1; /* if stopped then not repeatable */ }