注:以下内容来自朱老师物联网大讲堂课件
1.uboot命令体系基础
1.1 使用uboot命令
uboot启动后进入命令行环境下,在此输入命令按回车结束,uboot会收取这个命令然后解析,然后执行。
1.2 uboot命令体系实现代码在哪里
uboot命令体系的实现代码在uboot/common/cmd_xxx.c中。有若干个.c文件和命令体系有关。(还有command.c main.c也是和命令有关的)
1.3 每个命令对应一个函数
(1)每一个uboot的命令背后都对应一个函数。这就是uboot实现命令体系的一种思路和方法。这个东西和我们在裸机第十六部分shell中实现shell命令的方法是一样的。
(2)我们要找到每一个命令背后所对应的那个函数,而且要分析这个函数和这个命令是怎样对应起来的。
(3)一般情况命令的函数名就是对应命令前面加上do_,如:do_help
1.4 命令参数以argc&argv传给函数
(1)有些uboot的命令还支持传递参数。也就是说命令背后对应的函数接收的参数列表中有argc和argv,例如我们之前讲到过的bootm指令
举例分析,以help命令为例:
help命令背后对应的函数名叫:do_help。在uboot/common/command.c的236行。
int do_help (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
2.uboot命令解析和执行过程分析
2.1 从main_loop说起
(1)uboot启动的第二阶段,在初始化了所有该初始化的东西后,进入了一个死循环,死循环的循环体就是main_loop。
(2)main_loop函数执行一遍,就是一个boot倒计时、获取命令、解析命令、执行命令的过程。
main_loop函数中bootdelay的流程梳理
第一步:定义bootdelay 变量
第二步:判断环境变量中是否有设置bootdelay ,没有则设置默认值
第三步:判断bootdelay 是否大于0,getenv是否读取正常,abortboot 函数的作用是倒计时控制
abortboot函数解析
static __inline__ int abortboot(int bootdelay)
{
int abort = 0;
//如果有菜单则输出菜单
#ifdef CONFIG_MENUPROMPT
printf(CONFIG_MENUPROMPT);
#else
//我们这里执行的是else这部分,也就是我们启动时显示倒计时
printf("Hit any key to stop autoboot: %2d ", bootdelay);
#endif
#if defined CONFIG_ZERO_BOOTDELAY_CHECK
/*
* Check if key already pressed
* Don't check if bootdelay < 0
*/
if (bootdelay >= 0) {
if (tstc()) {
/* we got a key press */
(void) getc(); /* consume input */
puts ("\b\b\b 0");
abort = 1; /* don't auto boot */
}
}
#endif
//while循环实现的作用就是我们启动时倒计时和回车破坏自动启动
while ((bootdelay > 0) && (!abort)) {
int i;
--bootdelay;
/* delay 100 * 10ms */
for (i=0; !abort && i<100; ++i) {
if (tstc()) {
/* we got a key press */
abort = 1; /* don't auto boot */
bootdelay = 0; /* no more delay */
# ifdef CONFIG_MENUKEY
menukey = getc();
# else
(void) getc(); /* consume input */
# endif
break;
}
udelay(10000);
}
printf("\b\b\b%2d ", bootdelay);
}
putc('\n');
#ifdef CONFIG_SILENT_CONSOLE
if (abort)
gd->flags &= ~GD_FLG_SILENT;
#endif
return abort;
}
2.1.1 知识点:#ifdef和#if defined的差别
ifdef 只能在两者中选择是否有定义
#ifdef XXX
...