u-boot分析之命令实现(四)

目录

u-boot(四)命令实现


u-boot(四)命令实现

命令是如何实现的?

  1. 输入命令
  2. 执行函数,根据命令去寻找函数

所以会有一个命令的结构体[name,fun],该结构体含有命令的name和对应的fun函数。

分析run_command

函数原型如下 int run_command (const char *cmd, int flag)

  1. 处理, 空格,;
  2. 解析参数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"
}
  • repeatable 可重复,指的是直接按回车是否继续执行上次命令
  • usage,短的help,指的是直接输入help查看的所有命令显示的帮助
  • help,具体的help,指的是help cmd 查看的具体的信息

小结

  1. U-boot 的命令是用结构体存储的,这些结构体是用特殊的段属性集合到一块区域里面去,分散在各个文件中
  2. 命令解析的时候是去这个段去搜索的,这个段属性的地址是从__u_boot_cmd_start__u_boot_cmd_end,在链接脚本中定义的.
  3. 命令结构体
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"
);

makefile

修改commonmakefile,只需要在COBJS上加上cmd_hello.o

转载:https://www.cnblogs.com/zongzi10010/p/10023679.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值