find_cmd函数分析
一、概述
1、函数位置
common/command.c
2、函数功能分析
解析命令的关键环节是如何根据输入命令查找对应命令的信息,从而跳转到对应命令的函数处执行程序。这必然涉及到如何存放命令的详细信息这个问题。因为一种存法,对应一种查法,进而取法。也就是说,实际上是两个问题:
(1)命令的详细信息是如何存放的
(2)如何在命令存储区查找是否有与输入命令匹配的命令
就这两个问题,我们来分别分析uboot的设计方法。
二、".u_boot_cmd"环境变量存储区
1、命令详细信息存储结构体
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
};
typedef struct cmd_tbl_s cmd_tbl_t;
2、把命令的详细信息安排在".u_boot_cmd"存储区
(1)相关声明
#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}
## 代表字符串连接符
# 代表转换为字符串
(2)实例说明
int do_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{ } U_BOOT_CMD(
md, , , do_hello,
"md - memory display\n",
"[.b, .w, .l] address [# of objects]\n - memory display\n"
);
U_BOOT_CMD(
hello, 3, 1, do_hello,
"md - memory display\n",
"[.b, .w, .l] address [# of objects]\n - memory display\n"
);
展开后为:
cmd_tbl_t __u_boot_cmd_hello
__attribute__ ((unused,section (".u_boot_cmd")))
={
"hello", , , do_hello,
"md - memory display\n",
"[.b, .w, .l] address [# of objects]\n - memory display\n"
};
可见,实际上就是定义了一个cmd_tbl_t类型的变量"__u_boot_cmd_hello",并且强制性的将其存储在".u_boot_cmd"段,等号后边的就是该变量的初始值。
三、具体分析find_cmd函数
函数功能:查找命令是否存在,如果存在就将命令结构体地址返回
/***************************************************************************
* find command table entry for a command
*/
cmd_tbl_t *find_cmd (const char *cmd)
{
cmd_tbl_t *cmdtp;
cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start; /*Init value */
const char *p;
int len;
int n_found = 0;
/*
* Some commands allow length modifiers (like "cp.b");
* compare command name only until first dot.
*/
len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);
//获取命令的长度,因为uboot支持命令的简写,但是以'.'为分隔符
//下边的for循环就是在命令结构体存储区中,从前到后依次查找是否有匹配的命令
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++;
}
}
if (n_found == 1) { /* exactly one match */ //如果简写命令只有一个匹配,那么说明就是要找的命令
//但是,倘若超过一个就不知道所谓的简写是哪一个命令了
return cmdtp_temp;
}
return NULL; /* not found or ambiguous command */
}
参考资料:U-Boot启动第二阶段代码分析
find_cmd函数分析的更多相关文章
- split(),preg_split()与explode()函数分析与介
split(),preg_split()与explode()函数分析与介 发布时间:2013-06-01 18:32:45 来源:尔玉毕业设计 评论:0 点击:965 split()函数可以实 ...
- string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
- start_amboot()函数分析
一.整体流程 start_amboot()函数是执行完start.S汇编文件后第一个C语言函数,完成的功能自然还是初始化的工作 . 1.全局变量指针r8设定,以及全局变量区清零 2.执行一些类初始化函 ...
- uboot的jumptable_init函数分析
一.函数说明 函数功能:安装系统函数指针 函数位置:common/exports.c 二.函数分析 void jumptable_init (void) { int i; gd->jt = (v ...
- Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析
Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...
- 31.QPainter-rotate()函数分析-文字旋转不倾斜,图片旋转实现等待
在上章和上上上章: 28.QT-QPainter介绍 30.QT-渐变之QLinearGradient. QConicalGradient.QRadialGradient 学习了QPainter基础绘 ...
- 如何验证一个地址可否使用—— MmIsAddressValid函数分析
又是一篇内核函数分析的博文,我个人觉得Windows的内核是最好的老师,当你想实现一个功能之前可以看看Windows内核是怎么做的,说不定就有灵感呢:) 首先看下官方的注释说明: /*++ Routi ...
- STM32F10X固件库函数——串口清状态位函数分析
STM32F10X固件库函数——串口清状态位函数分析 最近在测试串口热插拔功能的时候,意外发现STM32F10X的串口库函数中,清理串口状态位函数稍稍有点不解.下面是改函数的源码: /******** ...
- 常用string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
随机推荐
- thinkphp 重定向redirect
/** * URL重定向 * @param string $url 重定向的URL地址 * @param integer $time 重定向的等待时间(秒) * @param string $msg ...
- HDU--5280(dp或枚举)
官方题解: 这个题有非常多O(n2)的算法.这里说一种:枚举每个区间,在枚举区间的同一时候维护区间内的最小值和区间和,将最小值与P的大小进行比較,贪心地取最大值就可以.注意若枚举到的区间是整个数组,则 ...
- C程序内存管理
C程序的内存管理 熟悉Java语言的肯定知道,Java中内存管理是由虚拟机帮助我们完毕的,在C/C++中可不是这样,程序猿须要自己去分配和回收内存空间.本文记录了C程序可运行文件的存储结构.在内存中的 ...
- 使用php glob函数查找文件,遍历文件目录(转)
函数说明:array glob ( string $pattern [, int $flags ] )功能:寻找与模式匹配的文件路径,返回包含匹配文件(目录)的数组(注:被检查的文件必须是服务器系统的 ...
- iOS-iPad开发之SplitViewController简单介绍
iOS-iPad开发之SplitViewController简单介绍 SplitViewController图形化创建 SplitViewController可以并列显示两个view,适用于基于nav ...
- [转] Scale-up 和Scale-out的区别
http://www.cnblogs.com/spork/archive/2009/12/29/1634766.html 来自原小站,曾经迷糊过的东西,表上来,希望对正在迷糊或即将迷糊的人有帮助. 谈 ...
- 含有GROUP BY子句的查询中如何显示COUNT()为0的成果(分享)
在SQL Server数据库查询中,为了对查询成果进行对比.解析,我们经常会用到GROUP BY子句以及COUNT()函数来对查询成果进行分类.统计等.然则我们在应用的过程中往往会存在一些题目,本文我 ...
- webGIS(离线版)研究路线归总
特注:不做详解,说明网上资源很多,找一篇,照着走一遍即可. 1.数据源要满足开源.Free且地理信息要完善 几经周折,选择了OSM,具体信息可以去其官方查看(它竟然把中国一分为二,大陆.台湾,坑爹!! ...
- 关于mssql数据库锁和事务隔离级别
事务隔离级别有4种,这4种级别只是对于读操作,也就是select有不同程度的支持, 读未提交:不会对事务里读出来的数据附加任何锁 读已提交:会对事务里读出来的数据附加共享锁,读完就释放共享锁,其他事务 ...
- rdlc报表
也是第一次接触报表这个东西.现在在我理解,报表无非就是两个内容,格式和数据. 格式没有多少了解,就记录了,以后再续.数据的绑定和结果的显示是怎么实现的呢? 今天的主角就是rdlc这个文件和Report ...