一、概述

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函数分析的更多相关文章

  1. split(),preg_split()与explode()函数分析与介

    split(),preg_split()与explode()函数分析与介 发布时间:2013-06-01 18:32:45   来源:尔玉毕业设计   评论:0 点击:965 split()函数可以实 ...

  2. string函数分析

    string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...

  3. start_amboot()函数分析

    一.整体流程 start_amboot()函数是执行完start.S汇编文件后第一个C语言函数,完成的功能自然还是初始化的工作 . 1.全局变量指针r8设定,以及全局变量区清零 2.执行一些类初始化函 ...

  4. uboot的jumptable_init函数分析

    一.函数说明 函数功能:安装系统函数指针 函数位置:common/exports.c 二.函数分析 void jumptable_init (void) { int i; gd->jt = (v ...

  5. Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析

    Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...

  6. 31.QPainter-rotate()函数分析-文字旋转不倾斜,图片旋转实现等待

    在上章和上上上章: 28.QT-QPainter介绍 30.QT-渐变之QLinearGradient. QConicalGradient.QRadialGradient 学习了QPainter基础绘 ...

  7. 如何验证一个地址可否使用—— MmIsAddressValid函数分析

    又是一篇内核函数分析的博文,我个人觉得Windows的内核是最好的老师,当你想实现一个功能之前可以看看Windows内核是怎么做的,说不定就有灵感呢:) 首先看下官方的注释说明: /*++ Routi ...

  8. STM32F10X固件库函数——串口清状态位函数分析

    STM32F10X固件库函数——串口清状态位函数分析 最近在测试串口热插拔功能的时候,意外发现STM32F10X的串口库函数中,清理串口状态位函数稍稍有点不解.下面是改函数的源码: /******** ...

  9. 常用string函数分析

    string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...

随机推荐

  1. 自己动手画一个HTML5的按钮

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  2. BootStrap-table 客户端分页和服务端分页的区别

    当服务器没有对数据进行分页时,前端页面设计又要求进行分页,要分开来设置. 服务端分页: responseHandler: function(data){ return data.response; } ...

  3. Jenkins的plugin开发

    Jenkins强大的功能主要靠其丰富的plugin体现,之前的一篇博客<Jenkins安装plugin>中介绍了如何找到并安装需要的plugin.虽然目前已经有大量非常优秀的plugin可 ...

  4. 使用jq工具在Shell命令行处理JSON数据

    由于近期要处理一些 JSON 数据格式.一大早经过一番搜索后,终于找到了 jq 这个非常棒的工具.jq 同意你直接在命令行下对 JSON 进行操作,包含分片.过滤.转换等等. 首先在mac下安装jq. ...

  5. DM8168 GPIO驱动与測试程序

    本次測试针对GPIO1进行,挑选了GP1[31],引脚的复用默认的就是GPIO 还是老规矩,贴上driver.c,Makefile,test.c: dm8168_gpio.c: #include &l ...

  6. mysqldump 定时任务 执行后备份的文件为空

    #!/bin/bash mysql_host="127.0.0.1" mysql_user="root" mysql_passwd="******** ...

  7. 在32位Windows 8或Windows 7上安装Windows Phone 8 SDK

    这需要一点技巧的,其实WPSDK8是支持32位系统的,可因为微软脑残的限制,安装方法如下: 这里必需要有一个工具,OllyDbg 2.0,去官网下载即可. 启动OD,在菜单打开选项窗口,在Events ...

  8. HttpContext.Current

    HttpContext. Response 直接这样写会报错 是因为 httpcontext没有提供response 这个静态的方法. 通过这样写就可以 ASP.NET还为它提供了一个静态属性Http ...

  9. java I/O的基本使用

    1.什么是I/O a.I/O也称为:输入输出,可以理解为In,Out b.I/O流:读取键盘键入的字符,硬盘上的文件 c.处理数据的类型分类:字节流.字符流 字节流:以Stream结尾的,可以处理图片 ...

  10. c#中使用数据读取器读取查询结果

    今天有时间了. 在看<c#数据库入门经典> ,总结数据读取器查询结果. 针对单个结果集使用读取器,有3中方法: String connString =..; String sql =@&q ...