u-boot-1.1.6分析(六)run_command

这一节的主要内容

一、分析run_command

二、自己写一个u-boot命令

 

在u-boot启动等待超时的过程中按下空格键,u-boot会进入菜单模式(用于调试)

run_command主要作用是在菜单模式中读取用户输入的字符串,根据字符串从表中提取参数、找到相应命令结构体,并调用命令结构体的功能函数,启动内核也是通过这个函数来进行的

 

分析run-command:

1、处理字符串

        clear_ctrlc();		/*去掉前面的空格*/
	if (!cmd || !*cmd) {	/*判断命令是否为空*/
		return -1;	/* empty command */
	}

	if (strlen(cmd) >= CFG_CBSIZE) {	/*判断命令长度是否合适*/
		puts ("## Command too long!\n");
		return -1;
	}


	while (*str) {	/*解析字符串并执行命令*/
		for (inquotes = 0, sep = str; *sep; sep++) {
			if ((*sep=='\'') &&
			    (*(sep-1) != '\\'))
				inquotes=!inquotes;

			if (!inquotes &&
			    (*sep == ';') &&	
			    ( sep != str) &&	
			    (*(sep-1) != '\\'))	
				break;
		}
		token = str;
		if (*sep) {
			str = sep + 1;	
			*sep = '\0';
		}
		else
			str = sep;	
#ifdef DEBUG_PARSER
		printf ("token: \"%s\"\n", token);
#endif
		process_macros (token, finaltoken);
		if ((argc = parse_line (finaltoken, argv)) == 0) {	/*提取参数*/
			rc = -1;	
			continue;
		}

2、根据字符串找到命令结构体

		if ((cmdtp = find_cmd(argv[0])) == NULL) {	/*查表找到命令*/
			printf ("Unknown command '%s' - try 'help'\n", argv[0]);
			rc = -1;	/* give up after bad command */
			continue;
		}

3、调用命令结构体的功能函数

		if (argc > cmdtp->maxargs) {	/*检查参数个数*/
			printf ("Usage:\n%s\n", cmdtp->usage);
			rc = -1;
			continue;
		}
#if (CONFIG_COMMANDS & CFG_CMD_BOOTD)
		if (cmdtp->cmd == do_bootd) {
#ifdef DEBUG_PARSER
			printf ("[%s]\n", finaltoken);
#endif
			if (flag & CMD_FLAG_BOOTD) {
				puts ("'bootd' recursion detected\n");
				rc = -1;
				continue;
			} else {
				flag |= CMD_FLAG_BOOTD;
			}
		}
#endif	
		if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {	/*执行命令*/
			rc = -1;
		}
		repeatable &= cmdtp->repeatable;
		if (had_ctrlc ())
			return 0;	
	}

 

 

其中cmd_tbl_t类型的结构体用于描述命令,结构体类型定义在u-boot-1.1.6/include/command.h

struct cmd_tbl_s {
	char		*name;		/*命令名称*/
	int		maxargs;	/*最大参数个数*/
	int		repeatable;	/*可重复的标志位*/				
	int		(*cmd)(struct cmd_tbl_s *, int, int, char *[]);	/*命令功能函数指针*/
	char		*usage;		/*短的帮助信息*/
#ifdef	CFG_LONGHELP
	char		*help;		/*长的帮助信息*/
#endif
#ifdef CONFIG_AUTO_COMPLETE
	int		(*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);
#endif
};


typedef struct cmd_tbl_s	cmd_tbl_t;

 

并且在该文件还定义了一个重要的宏:

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}

 

各种命令的定义在u-boot-1.1.6/common的cmd_xxx.c文件中,如cmd_bootm.c中有如下定义:

U_BOOT_CMD(
 	bootm,	CFG_MAXARGS,	1,	do_bootm,
 	"bootm   - boot application image from memory\n",
 	"[addr [arg ...]]\n    - boot application image stored in memory\n"
 	"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
 	"\t'arg' can be the address of an initrd image\n"
#ifdef CONFIG_OF_FLAT_TREE
	"\tWhen booting a Linux kernel which requires a flat device-tree\n"
	"\ta third argument is required which is the address of the of the\n"
	"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
	"\tuse a '-' for the second argument. If you do not pass a third\n"
	"\ta bd_info struct will be passed instead\n"
#endif
);

 

将宏展开后:

cmd_tbl_t __u_boot_cmd_bootm Struct_Section = {
 	bootm,	CFG_MAXARGS,	1,	do_bootm,
 	"bootm   - boot application image from memory\n",	/*短的帮助信息*/
 	"[addr [arg ...]]\n    - boot application image stored in memory\n"
 	"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
 	"\t'arg' can be the address of an initrd image\n"
#ifdef CONFIG_OF_FLAT_TREE
	"\tWhen booting a Linux kernel which requires a flat device-tree\n"
	"\ta third argument is required which is the address of the of the\n"
	"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
	"\tuse a '-' for the second argument. If you do not pass a third\n"
	"\ta bd_info struct will be passed instead\n"
#endif
};

 

这个结构体中的函数成员do_bootm的头部为

int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

 

二、自己写一个u-boot命令

知道这些,就可以仿照实现自己需要的u-boot命令,例如实现一个打印语句”test\r\n”的命令

1、新建文件cmd_test.c,放在u-boot-1.1.6/common中

2、修改u-boot-1.1.6/common/Makefile,在55行添加

COBJS += cmd_test.o

3、在cmd_test.c中填充以下内容

#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <image.h>
#include <malloc.h>
#include <zlib.h>
#include <bzlib.h>
#include <environment.h>
#include <asm/byteorder.h>


int do_test (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
printf(“test\r\n”);
return 1;
}
U_BOOT_CMD(
 	test, 	CFG_MAXARGS,	1,	do_test,
 	"short help\n",
 	"long help\n"
);

4、重新编译烧写u-boot,即可在u-boot菜单模式中输入test来执行自己编写的命令了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值