WDS1期第9课 uboot 4 之uboot命令分析

在这里插入图片描述

根据命令找到对应的函数
命令结构体

分离开命令,命令中有 ; 等,还是在common/main.c中,

		/*
		 * Find separator, or string end
		 * Allow simple escape of ';' by writing "\;"
		 */
		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;
		}

		/*
		 * Limit the token to data between separators
		 */
		token = str;
		if (*sep) {
			str = sep + 1;	/* start of command for next pass */
			*sep = '\0';
		}
		else
			str = sep;	/* no more commands for next pass */

处理一些宏,如通过网卡下载文件时产生的宏,

	/* find macros in this tokenand replace them */
	process_macros (token, finaltoken);

提取命令和参数,argv[0](命令), argv[1](参数)等等

	/* Extract arguments */
	if ((argc = parse_line (finaltoken, argv)) == 0) {
		rc = -1;	/* no command at all */
		continue;
	}

查找命令

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

命令结构体cmd_tbl_s,在include/command.h中,命令名字,参数,是否可重复(回车就可以再次执行),函数指针执行命令,短(help)长(help print)帮助信息,

/*
 * Monitor Command Table
 */
struct cmd_tbl_s {
	char		*name;		/* Command Name			*/
	int		maxargs;	/* maximum number of arguments	*/
	int		repeatable;	/* autorepeat allowed?		*/
					/* Implementation function	*/
	int		(*cmd)(struct cmd_tbl_s *, int, int, char *[]);
	char		*usage;		/* Usage message	(short)	*/
#ifdef	CFG_LONGHELP
	char		*help;		/* Help  message	(long)	*/
#endif
#ifdef CONFIG_AUTO_COMPLETE
	/* do auto completion on the arguments */
	int		(*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);
#endif
};

查找命令find_cmd,在common/command.c中,for循环依次在__u_boot_cmd_start~__u_boot_cmd_end中查找,查找到了返回结构体,没有则继续往下查找,

	for (cmdtp = &__u_boot_cmd_start;
	     cmdtp != &__u_boot_cmd_end;
	     cmdtp++) {
		if (strncmp (cmd, cmdtp->name, len) == 0) {
			if (len == strlen (cmdtp->name))
				return cmdtp;	/* full match */

			cmdtp_temp = cmdtp;	/* abbreviated command ? */
			n_found++;
		}

__u_boot_cmd_start~__u_boot_cmd_end这俩东西在代码中找不到,但可以通过链接脚本(board/100ask24x0/u-boot.lds)传入,

	. = .;
	__u_boot_cmd_start = .;
	.u_boot_cmd : { *(.u_boot_cmd) }
	__u_boot_cmd_end = .;

想查看究竟这俩中间放了些什么命令,需要在include/command.h中找到u_boot_cmd的定义

#define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))

假设命令为bootcmd nand read 0x30007fc0 kernel;bootm 0x30007fc0
以bootm命令为例,找到这个宏U_BOOT_CMD,在common/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
);

定义之处还是在include/command.h中,

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

展开如下,cmd_tbl_t为结构体类型,Struct_Section为前面的定义的宏__attribute__ ((unused,section (".u_boot_cmd")))。定义一个结构体变量__u_boot_cmd_bootm,其有段属性被强制设置为".u_boot_cmd",这个东西在lds中。
#name, maxargs, rep, cmd, usage, help分别在这个宏U_BOOT_CMD中对应,usage和help为字符串,

cmd_tbl_t __u_boot_cmd_bootm __attribute__ ((unused,section (".u_boot_cmd"))) = {"bootm", CFG_MAXARGS, 1, do_bootm, 小help, 大help}

===最后:在代码段用U_BOOT_CMD表示的东西最终被解析成

cmd_tbl_t __u_boot_cmd_bootm __attribute__ ((unused,section (".u_boot_cmd"))) = {"bootm", CFG_MAXARGS, 1, do_bootm, 小help, 大help}

这就相当于定义了一个结构体,这个结构体有个属性强制把他的段指定成".u_boot_cmd",所以所有的命令都会被集中到lds中的.u_boot_cmd : { *(.u_boot_cmd) }这里。=====

在uboot中增加一个自定义命令

uboot命令都放在common/下吧,
命名为cmd_my_hello.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_my_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
    int i = 0;
    printf ("my_hello add uboot cmd\n");
    for (i=0; i<argc; ++i)
    {
        printf("argv[%d]: %s\n", i, argv[i]);
    }
    return 0;
}

U_BOOT_CMD(
 	my_hello,	CFG_MAXARGS,	1,	do_my_hello,
 	"my_hello short help, just for test.\n",
 	"my_hello, long help\n"
 	"\tmy_hello, long help1....\n"
 	"\tmy_hello, long help2....\n"
);

修改common/Makefile, 只需要添加就是了,

 s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
 usb.o usb_kbd.o usb_storage.o \
 virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_suspend.o \
 cmd_my_hello.o  # 自定义uboot命令

重新编译uboot,cd到uboot根目录,make。

根目录下生成的u-boot.bin烧写到开发板就ok了。

检查是否添加,命令成功,

OpenJTAG> help 

在这里插入图片描述

OpenJTAG> help my_hello   

在这里插入图片描述

OpenJTAG> my_hello 

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值