如果配置了启动延迟功能,U-Boot等待用户从控制台(一般为串口)输入字符,等待的时间由顶层配置文件中的宏定义 CONFIG_BOOTDELAY 决定 。在此期间,只要用户按下任意按键就会中断等待,进入命令行输入模式。
如果没有配置启动延时功能或者启动延时超过了设置的时间, U-Boot 运行启动命令行参数,启动命令参数在顶层配置文件中,由 CONFIG_BOOTCOMMAND宏定义。
命令行输入模式实际上是一个死循环,循环体简化后如下所示:
for (;;) {
len = readline (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 (len == -1)
puts ("< INTERRUPT >n");
else
rc = run_command(lastcommand, flag);
if (rc <= 0) {
/* invalid command or not repeatable, forget it */
lastcommand[0] = 0;
}
}
每次循环调用readline函数从控制台读取命令行,并且读取到的字符存储在console_buffer缓冲区中。
console_buffer缓冲区的长度在顶层文件中通过CONFIG_SYS_CBSIZE宏定义。
当该函数在接收到一个回车键时认定为命令行输入结束,返回命令行长度len。
如果len大于0,将存储在缓冲区的命令行拷贝至静态数组lastcommand中,flag设置为0。
如果len等于0,即readline函数仅仅接收到一个回车键,即直接返回,flag设置为CMD_FLAG_REPEAT,lastcommand数组存放的数据不变。
flag用于标志是否重复上次操作,每个命令都有一个 repeatable标志,当命令的该标志为1时,此时,命令能够重复操作。
把lastcommand和flag作为run_command函数的参数,进而调用run_command函数。
从 run_command 函数是否会返回的角度看,U-Boot 的命令分为两类。
一类是函数返回数值rc,rc小于等于0 ,则传入的命令行参数有误,命令无效,此时把lastcommand数组清零,不再执行重复操作。
另外一类是不再返回,一去不再复返 ,例如bootm、go等命令,这类用于启动内核,将CPU的管理权从U-Boot交付给内核,完成自己启动内核的终极使命。
传入的 lastcommand 参数仅仅是 readline 函数读取到用户输入的字符,接下来最主要的工作是解析命令行。
首先判断传入的lastcommand参数是否为空,如果是返回−1,否则继续往下解析。截取函数的关键代码如下,str指针指向 lastcommand区域 。
while (*str) {
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;
}
U-Boot允许命令行存在多个命令,命令间用“;”或者“;”字符分割。
token = str;
if (*sep) {
str = sep + 1; /* start of command for next pass */
*sep = '�';
}
else
str = sep; /* no more commands for next pass */
/* Extract arguments */
if ((argc = parse_line (finaltoken, argv)) == 0) {
rc = -1; /* no command at all */
continue;
}
if (cmd_process(flag, argc, argv, &repeatable, NULL))
rc = -1;
首先解析一个命令,token指向待解析命令的地址。
parse_line函数分离出命令的各个参数,分别存放在argv中,参数的数目为argc,接着调用common/command.c文件中的cmd_process函数处理解析得到的命令。
值得注意的是, 命令的第一个参数是命令的名称 。当前命令处理完毕后, token指向命令行中的下一个命令,直到所有的命令都处理完毕。
全部0条评论
快来发表一下你的评论吧 !