uboot自有命令功能函数实现细节(四)

uboot启动之后可以响应键盘输入,执行自带命令,完成各种功能,文本主要围绕uboot自有命令实现细节。
接着上节的main_loop函数,删除不必要细节,精简如下:

void main_loop (void)
{
	static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
	int len;
	int rc = 1;
	int flag;
	char *s;
	int bootdelay;

	s = getenv ("bootdelay");
	bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;

	s = getenv ("bootcmd");

	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;
		}
	}
}

主要关注getenv以及run_command函数,在调用main_loop之前,即board_init_r函数体中调用env_relocate()来初始化与环境变量相关的信息:

void env_relocate (void)
{
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
	extern void env_reloc(void);

	env_reloc();
#endif
	if (gd->env_valid == 0) {
#if defined(CONFIG_ENV_IS_NOWHERE)	/* Environment not changable */
		set_default_env(NULL);
#else
		show_boot_progress (-60);
		set_default_env("!bad CRC");
#endif
	} else {
		env_relocate_spec ();
	}
}

我们按默认的环境变量来分析set_default_env:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
函数himort_r主要是进行词法分析,注释也有说明:
Import linearized data into hash table.
This is the inverse function to hexport(): it takes a linear list
of “name=value” pairs and creates hash table entries from it.

env_htab是个全局变量,存储进行词法分析之后的相关信息:
在这里插入图片描述
现在回到getevn函数:
在这里插入图片描述
该函数的作用是返回在环境变量中的数据,举个例子,在const uchar default_environment[]有如下环境参数:
“bootdelay=3 ”,
那么getenv (“bootdelay”)返回的就是=之后的字符串——“3”,称之为数据部分。
同理bootcmd环境参数的数据部分如下:

	"if mmc rescan ${mmcdev}; then " \
		"if run loadbootscript; then " \
			"run bootscript; " \
		"else " \
			"if run loaduimage; then " \
				"run mmcboot; " \
			"else run nandboot; " \
			"fi; " \
		"fi; " \
	"else run nandboot; fi" "\0"

以上字符串也就是run_command的第一个参数cmd:
*int run_command (const char cmd, int flag)
run_command在字符串中提取一系列参数,最后查找相应的命令:
在这里插入图片描述在这里插入图片描述
这里要去查看u-boot.lds文件:
在这里插入图片描述
处于段.u_boot_cmd的数据,那么查找相关信息:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
举个例子,假设执行 **“run nandboot”**命令:
需要执行 字符 run对应的命令:
在这里插入图片描述
将宏展开如下:
在这里插入图片描述
那么之前find_cmd传入参数"run",返回 __u_boot_cmd_run结构,接着就会执行do_run函数:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里会继续之前的步骤,解析nandboot符号来找到相应的命令函数:在这里插入图片描述
基本上uboot所有的自有命令都是类似过程,通过分析命令函数也可以加深对自有命令功能的理解,可以模仿创建自有命令。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值