版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012351051/article/details/88044912
main_loop()函数是start_armboot函数执行到最后的一条函数,start_armboot进行各种初始化动作后,循环执行main_loop,main_loop函数在/common/main.c中,从该文件名也能知道,该函数才是u-boot最重要的功能实现---引导内核、功能交互,main_loop可以理解为u-boot的shell,通过该函数,程序员可以与u-boot进行交互,当然如果程序员无任何动作(串口无字符串输入),u-boot会自动的干它最重要的工作---引导内核kernel。自然,我们根据条件编译结果来分析main_loop函数,分析如下:
void main_loop (void)
{
static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
int len;
int rc = 1;
int flag;
char *s;
int bootdelay;
//u-boot 版本号-环境变量设定
{
extern char version_string[];
setenv ("ver", version_string); /* set version variable */
}
//u-boot 命令自动补全功能安装
install_auto_complete();
s = getenv ("bootdelay");
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
s = getenv ("bootcmd");
debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
//abortboot函数是判断串口有没有字符串,如果没有字符串返回0,
//自然就运行bootcmd命令,也就是自动引导kernel
//而如果有字符串输入,则返回1,那么下面的"!abortboot == 0",
//自然就不去执行bootcmd命令,运行下面的for(;)命令,等待用户与u-boot交互
if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
run_command (s, 0);
}
/*
* Main Loop for Monitor Command Processing
*/
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;
}
}
}
你没有看错,经过条件编译(mx28_evk.h配置)后,main_loop函数就是上面的那么简单,其实最主要的就2个功能:
(1) 通过abortboot 函数判断串口是否有字符串输入,如果没有字符串返回0,自然就运行bootcmd命令,也就是自动引导kernel,而如果有字符串输入,则返回1,那么下面的"!abortboot == 0",自然就不去执行bootcmd命令,运行下面的for(;)命令,等待用户与u-boot交互。
(2)如果不是自动引导内核, 进入程序员与u-boot交互,也可以直接运行 run bootcmd命令来手动引导kernel。