目录
title: u-boot(四)命令实现
tags: linux
date: 2018-09-25 23:13:05
---
命令是如何实现的?
所以会有一个命令的结构体[name,fun]
函数原型如下 int run_command (const char *cmd, int flag)
处理, 空格,;
等
解析参数parse_line (finaltoken, argv)
example: md.w 0 ------>argv[0]= "md.w", argv[1]=" 0"
?```
/* Extract arguments */
if ((argc = parse_line (finaltoken, argv)) == 0) {
rc = -1; /* no command at all */
continue;
}
?```
命令搜索if ((cmdtp = find_cmd(argv[0])) == NULL)
,可以发现结构体
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
};
查看函数,可以发现是在__u_boot_cmd_start
和__u_boot_cmd_end
中遍历,这个地址是在链接脚本中定义的,也就是命令这个东西,有一个特殊的属性,定位到某个地址.
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
搜索这个段属性.u_boot_cmd
,在include\command.h
有这么一个宏
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
再搜索下这个宏
#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_CMD
,可以发现其实就是命令了,搜索下命令bootm
,在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"
);
尝试着展开这个宏,可以发现就是定义了一个段属性特殊的结构体,也就是命令结构体
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"
}
U-boot 的命令是用结构体存储的,这些结构体是用特殊的段属性集合到一块区域里面去,分散在各个文件中
命令解析的时候是去这个段去搜索的,这个段属性的地址是从__u_boot_cmd_start
到__u_boot_cmd_end
,在链接脚本中定义的.
命令结构体
struct cmd_tbl_s ;
参考common/cmd_bootm.c
的头文件,编写源代码cmd_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_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int i ;
printf ("hello world %d \n,", argc);
//打印下参数
for(i=0;i<argc;i++)
{
printf ("argv[%d] is %s \n",i,argv[i]);
}
return 0;
}
U_BOOT_CMD(
hello, CFG_MAXARGS, 1, do_hello,
"this is short help for hello just test\n",
"this is long help for hello just test\n"
);
修改common
的makefile
,只需要在COBJS上加上cmd_hello.o
原文:https://www.cnblogs.com/zongzi10010/p/10023679.html