uboot命令的实现以及解析
2013-03-18 15:36
405 查看
解析run_command
1.argc = parse_line (finaltoken, argv) //解析命令的参数有几个
2.cmdtp = find_cmd(argv[0] //获取命令的结构体
3.(cmdtp->cmd) (cmdtp, flag, argc, argv) //执行命令的实现函数
在分析之前先说一个命令的结构体
1.结构体cmd_tbl_t *cmdtp;
定义如下:typedef struct cmd_tbl_s cmd_tbl_t;
cmdtp = find_cmd(argv[0])//这个函数通过argv[0]也即命令的名字来找到cmd_tbl_s的结构体。
如果没有找到输入命令的结构体,则会打印错误输出信息:
Unknown command '%s' - try 'help'
下面看下函数find_cmd是如何处理的:
其中__u_boot_cmd_start与__u_boot_cmd_end的定义是在链接脚本u-boot.lds中定义:
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
这两个段之间放的就是uboot的命令,.u_boot_cmd段
定义如下:
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
这句话的意思是Struct_Section的宏定以为一个属性,这个属性转换为 .u_boot_cmd段
下面就看看Struct_Section被哪些cmd使用到了。
经过source insight搜索,发现Struct_Section 在另一个宏U_BOOT_CMD中使用到了,
下面自己添加一个命令的实例cmd_hello.c:
1.argc = parse_line (finaltoken, argv) //解析命令的参数有几个
2.cmdtp = find_cmd(argv[0] //获取命令的结构体
3.(cmdtp->cmd) (cmdtp, flag, argc, argv) //执行命令的实现函数
在分析之前先说一个命令的结构体
1.结构体cmd_tbl_t *cmdtp;
定义如下:typedef struct cmd_tbl_s cmd_tbl_t;
struct cmd_tbl_s { char *name; /* Command Name 命令的名字*/ int maxargs; /* maximum number of arguments 命令的最大参数的个数*/ int repeatable; /* autorepeat allowed? 命令是否可以重复,比如执行过一个命令后,再按下Enter重复之前的命令*/ /* 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 };重要的函数;
cmdtp = find_cmd(argv[0])//这个函数通过argv[0]也即命令的名字来找到cmd_tbl_s的结构体。
如果没有找到输入命令的结构体,则会打印错误输出信息:
Unknown command '%s' - try 'help'
下面看下函数find_cmd是如何处理的:
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段之间一一的和cmd name进行比对,如果匹配上,则返回该命令的cmdtp结构体。
其中__u_boot_cmd_start与__u_boot_cmd_end的定义是在链接脚本u-boot.lds中定义:
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
这两个段之间放的就是uboot的命令,.u_boot_cmd段
定义如下:
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
这句话的意思是Struct_Section的宏定以为一个属性,这个属性转换为 .u_boot_cmd段
下面就看看Struct_Section被哪些cmd使用到了。
经过source insight搜索,发现Struct_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就是uboot命令的宏.继续使用si搜索U_BOOT_CMD,发现这个宏在很多的文件中使用,选择一个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 __attribute__ ((unused,section (".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,属性强制设为.u_boot_cmd段,这也就解释了为什么uboot命令存放在__u_boot_cmd_start 与__u_boot_cmd_end 之间的原因了。
下面自己添加一个命令的实例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[]) { printf("Hello World\n"); return 0; } U_BOOT_CMD( hello, CFG_MAXARGS, 1, do_hello, "hello - hello for test\n", "Hello long test........\n" );修改Makefile,在COBJS = 后面加上cmd_hello.o重新编译即可.
相关文章推荐
- uboot之bootm以及go命令的实现
- zuul实现动态路由以及相关源码解析
- 【总结】java命令解析以及编译器,虚拟机如何定位类
- 解析如何在C语言中调用shell命令的实现方法
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复
- 【总结】java命令解析以及编译器,虚拟机如何定位类
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)
- 构建分离解析的域名服务器,以及实现SNAT和DNAT 转换
- 华为初命令实践!两个PC机,两个路由器,实现PC机ping通以及静态路由配置。
- uboot命令分析+实现
- for_each,count,mismatch等STL算法在VS2013下的实现以及辅助函数的源码解析
- 模拟Spring解析xml文件,以及实现IOC (DI)的示例
- Haproxy和pacemaker结合corosync实现负载均衡高可用,以及crm命令的使用
- 使用bind实现DNS主服务器的配置以及正向解析、反向解析、主从复制
- redis原理-对象以及命令解析与执行
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复
- 解析如何在C语言中调用shell命令的实现方法【转】
- Linux grep命令分析以及C语言版本的实现
- php DOM解析xml文档以及对节点增删改查实现
- u-boot学习(四):u-boot常用命令以及uboot命令的添加