3 学习笔记——函数void main_loop (void)注释
来源:互联网 发布:淘宝有没有投诉电话 编辑:程序博客网 时间:2024/06/05 12:49
- 版本号:2010.06
- 所有的初始化完毕后,要进入命令行模式,等待输入参数或者引导内核启动
- void main_loop (void)
- {
- #ifndefCONFIG_SYS_HUSH_PARSER
- static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
- int len;
- int rc = 1;
- int flag;
- #endif
-
- #ifdefined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
- char *s;
- int bootdelay;
- #endif
- #ifdef CONFIG_PREBOOT
- char*p;
- #endif
- #ifdefCONFIG_BOOTCOUNT_LIMIT
- unsigned long bootcount = 0;
- unsigned long bootlimit = 0;
- char *bcs;
- char bcs_set[16];
- #endif /*CONFIG_BOOTCOUNT_LIMIT */
-
- #if defined(CONFIG_VFD)&& defined(VFD_TEST_LOGO)
- ulong bmp = 0; /*default bitmap */
- extern int trab_vfd (ulong bitmap);
-
- #ifdefCONFIG_MODEM_SUPPORT
- if (do_mdm_init)
- bmp = 1; /*alternate bitmap */
- #endif
- trab_vfd(bmp);
- #endif /*CONFIG_VFD && VFD_TEST_LOGO */
-
- #ifdef CONFIG_BOOTCOUNT_LIMIT开发板没有配置该信息
- bootcount = bootcount_load(); 加载保存的启动次数
- bootcount++; 启动次数加1
- bootcount_store (bootcount); 更新启动次数
- sprintf (bcs_set, "%lu", bootcount); 打印启动次数
- setenv ("bootcount", bcs_set);
- bcs = getenv ("bootlimit");
- bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0;
- #endif /*CONFIG_BOOTCOUNT_LIMIT */
- //启动次数限制功能,限制用户的启动次数,主要是license限制用户启动系统
- #ifdefCONFIG_MODEM_SUPPORT 开发板没有配置
- debug ("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init);
- if (do_mdm_init) {
- char *str = strdup(getenv("mdm_cmd"));
- setenv ("preboot", str); /* set or delete definition */
- if (str != NULL)
- free (str);
- mdm_init(); /* wait for modem connection */
- }
- #endif /* CONFIG_MODEM_SUPPORT */
-
- #ifdefCONFIG_VERSION_VARIABLE
- {
- extern char version_string[];
-
- setenv ("ver", version_string); /* set version variable */设置版本号信息变量
- }
- #endif /*CONFIG_VERSION_VARIABLE */
-
- #ifdef CONFIG_SYS_HUSH_PARSER
- u_boot_hush_start ();// 不知什么功能
- #endif
-
- #ifdefined(CONFIG_HUSH_INIT_VAR)
- hush_init_var ();//
- #endif
-
- #ifdefCONFIG_AUTO_COMPLETE
- install_auto_complete();//安装自动补全函数
- #endif
-
- #ifdef CONFIG_PREBOOT
- if ((p = getenv ("preboot")) != NULL) {
- # ifdef CONFIG_AUTOBOOT_KEYED
- int prev = disable_ctrlc(1); /* disable Control C checking */使能组合键功能
- # endif
-
- # ifndef CONFIG_SYS_HUSH_PARSER
- run_command (p, 0);
- # else
- parse_string_outer(p,FLAG_PARSE_SEMICOLON |
- FLAG_EXIT_FROM_LOOP);
- # endif
-
- # ifdef CONFIG_AUTOBOOT_KEYED
- disable_ctrlc(prev); /* restore Control C checking */
- # endif
- }
- #endif /* CONFIG_PREBOOT */
-
- #ifdefined(CONFIG_UPDATE_TFTP)// 设置版本号信息变量
- update_tftp ();
- #endif /*CONFIG_UPDATE_TFTP */
- //在进入主循环之前,如果配置了启动延迟功能,等待用户从串口或者网络输入,
- #ifdefined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
- s = getenv ("bootdelay");
- bootdelay = s ? (int)simple_strtol(s, NULL, 10) :CONFIG_BOOTDELAY;// 启动延迟
-
- debug ("### main_loop entered: bootdelay=%d\n\n",bootdelay);
-
- # ifdefCONFIG_BOOT_RETRY_TIME
- init_cmd_timeout ();// 初始化命令行超时机制
- # endif /* CONFIG_BOOT_RETRY_TIME */
-
- #ifdef CONFIG_POST
- if (gd->flags & GD_FLG_POSTFAIL) {
- s = getenv("failbootcmd");
- }
- else
- #endif /* CONFIG_POST*/
- #ifdefCONFIG_BOOTCOUNT_LIMIT
- if (bootlimit && (bootcount > bootlimit)) {// 检查是否超过启动次数限制
- printf ("Warning: Bootlimit (%u) exceeded. Usingaltbootcmd.\n",
- (unsigned)bootlimit);
- s = getenv ("altbootcmd");
- }
- else
- #endif /*CONFIG_BOOTCOUNT_LIMIT */
- s = getenv("bootcmd");// 获取引导命令到S变量中
-
- debug ("### main_loop: bootcmd=\"%s\"\n",s ? s : "<UNDEFINED>");
-
- if (bootdelay >= 0 && s && !abortboot(bootdelay))
- {//如果延时大于等于0,并且在延时过程中没有接收到按键,则引导内核启动
- # ifdef CONFIG_AUTOBOOT_KEYED
- intprev = disable_ctrlc(1); /* disableControl C checking */禁止组合键功能
- # endif
-
- # ifndef CONFIG_SYS_HUSH_PARSER
- run_command (s, 0);//无输入命令,则执行bootcmd
- # else
- parse_string_outer(s,FLAG_PARSE_SEMICOLON |
- FLAG_EXIT_FROM_LOOP); //不知什么功能
- # endif
-
- # ifdef CONFIG_AUTOBOOT_KEYED
- disable_ctrlc(prev); /* restore Control C checking */禁止组合键功能
- # endif
- }
-
- # ifdef CONFIG_MENUKEY
- if (menukey == CONFIG_MENUKEY) {//检查是否支持菜单按键
- s = getenv("menucmd");
- if (s) {
- # ifndefCONFIG_SYS_HUSH_PARSER
- run_command (s, 0); //执行menucmd
- # else
- parse_string_outer(s, FLAG_PARSE_SEMICOLON |
- FLAG_EXIT_FROM_LOOP);
- # endif
- }
- }
- #endif /*CONFIG_MENUKEY */
- #endif /* CONFIG_BOOTDELAY */
-
- #ifdefCONFIG_AMIGAONEG3SE 开发板没有配置
- {
- extern voidvideo_banner(void);
- video_banner();
- }
- #endif
-
- /*
- * Main Loop for Monitor Command Processing
- */
- //循环使用readline函数从控制台即串口读取用户的输入,然后解析,如何解析参考run_command()函数的定义
- #ifdef CONFIG_SYS_HUSH_PARSER
- parse_file_outer();
- /*This point is never reached */永远执行不到这里
- for(;;);
- #else
- for (;;)
- {
- #ifdefCONFIG_BOOT_RETRY_TIME 开发板没有配置
- if(rc >= 0) {
- /*Saw enough of a valid command to
- * restart the timeout.
- */等到一个有效的命令则,复位超时时间
- reset_cmd_timeout();//复位超时时间
- }
- #endif
- len = readline (CONFIG_SYS_PROMPT);
- // CONFIG_SYS_PROMPT = "U-Boot> ",判断输入的命令的长度
-
- flag= 0; /* assume no special flags for now*/置一个标记位,有新的命令输入
- if(len > 0) // 对不同的输入命令的长度做出不同的处理
- strcpy(lastcommand, console_buffer);//将命令拷贝到lastcommand中
- elseif (len == 0)
- flag|= CMD_FLAG_REPEAT;//未输入命令,标记为最后输入的那个命令
- #ifdef CONFIG_BOOT_RETRY_TIME
- elseif (len == -2) { //超时处理
- /*-2 means timed out, retry autoboot
- */
- puts ("\nTimed out waiting forcommand\n");
- # ifdefCONFIG_RESET_TO_RETRY
- /* Reinit board to run initializationcode again */
- do_reset (NULL, 0, 0, NULL); //复位重启
- # else
- return; /*retry autoboot */
- # endif
- }
- #endif
-
- if(len == -1)
- puts("<INTERRUPT>\n");//输入命令被中断
- else
- rc= run_command (lastcommand,flag);
- //进入正常的命令处理,输入的命令,保存在lastcommand中,flag标记有新的命令输入
-
- if (rc <= 0) {
- /*invalid command or not repeatable, forget it *///命令无效,不能执行丢弃
- lastcommand[0]= 0;
- }
- }
- #endif/*CONFIG_SYS_HUSH_PARSER*/
- }
-
- 着重分析run_command
- 该函数主要是对用户输入的命令或者是自启动命令的语法分析,从中获取命令参数等信息,并查找一张系统保存的命令表,找到该命令对应的处理函数,调用相应的命令处理
- /****************************************************************************
- * returns:
- * 1 - command executed, repeatable
- * 0 - command executed but not repeatable,interrupted commands are
- * always considered not repeatable
- * -1 -not executed (unrecognized, bootd recursion or too many args)
- * (If cmd is NULL or "" or longer than CONFIG_SYS_CBSIZE-1 it is
- * considered unrecognized)
- *
- * WARNING:
- *
- * We must create a temporary copy of thecommand since the command we get
- * may be the result from getenv(), whichreturns a pointer directly to
- * the environment data, which may changemagicly when the command we run
- * creates or modifies environment variables(like "bootp" does).
- */
-
- int run_command (const char *cmd, int flag)
- {
- cmd_tbl_t *cmdtp;
- char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */工作命令拷贝区
- char *token; /*start of token in cmdbuf */ 指向cmdbuf的首地址
- char *sep; /*end of token (separator) in cmdbuf */指向cmdbuf的尾地址
- char finaltoken[CONFIG_SYS_CBSIZE];
- char *str = cmdbuf;
- char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
- int argc, inquotes;
- int repeatable = 1;
- int rc = 0;
- #ifdef DEBUG_PARSER 调试阶段使用,打印信息调试
- printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
- puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */
- puts ("\"\n");
- #endif
-
- clear_ctrlc(); /*forget any previous Control C */去掉组合键
- if (!cmd || !*cmd) { //对输入命令的有效性进行判断
- return -1; /*empty command */ 空命令之间返回-1
- }
- if (strlen(cmd) >= CONFIG_SYS_CBSIZE) {// 命令长度太长,不执行,之间返回-1
- puts ("## Command too long!\n");
- return -1;
- }
- strcpy (cmdbuf, cmd);// 将命令从cmd拷贝到工作区cmdbuf中
- /*Process separators and check for invalid
- * repeatable commands
- */
- #ifdef DEBUG_PARSER
- printf ("[PROCESS_SEPARATORS] %s\n", cmd);
- #endif
- while (*str) { // char *str = cmdbuf;判断输入命令是否到结束符
- /*
- * Findseparator, or string end
- * Allow simpleescape of ';' by writing "\;"
- */
- for (inquotes = 0, sep = str; *sep; sep++) { // 对输入命令的语法分析
- if ((*sep=='\'') &&
- (*(sep-1) != '\\'))
- inquotes=!inquotes;
- if (!inquotes &&
- (*sep== ';') && /* separator */
- ( sep!= str) && /* past stringstart */
- (*(sep-1) != '\\')) /* and NOTescaped */
- break;
- }
- /*
- * Limit the token to data between separators
- */
- token = str; //指向命令的开始位置
- if (*sep) {
- str = sep + 1; /*start of command for next pass */
- *sep = '\0';
- }
- else
- str = sep; /*no more commands for next pass */
- #ifdef DEBUG_PARSER 调试阶段使用,打印信息调试
- printf ("token: \"%s\"\n", token);
- #endif
- /* find macros in this token and replace them */
- process_macros(token, finaltoken);//找个输入命令中的宏并且替换它
- /* Extract arguments */
- if ((argc = parse_line (finaltoken,argv))== 0) {// 提取参数,将参数用/0隔开,并将处理过的命令格式存入argv[17]数组中
- 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;
- }
- #if defined(CONFIG_CMD_BOOTD)
- /* avoid "bootd" recursion *///避免"bootd"递归
- if (cmdtp->cmd == do_bootd) {
- #ifdef DEBUG_PARSER 调试阶段使用,打印信息调试
- printf ("[%s]\n", finaltoken);
- #endif
- if (flag & CMD_FLAG_BOOTD) {
- puts ("'bootd' recursiondetected\n");
- rc = -1;
- continue;
- } else {
- flag |= CMD_FLAG_BOOTD;
- }
- }
- #endif
- /* OK - call function to do the command *///该命令正确,调用函数执行该命令
- if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
- rc = -1;
- }
- repeatable &= cmdtp->repeatable;
- /* Did the user stop this? *///用户执行到此停止
- if (had_ctrlc ())
- return -1; /*if stopped then not repeatable */
- }
- return rc ? rc : repeatable;
- }