Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1183510
  • 博文数量: 221
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2139
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(221)

文章存档

2024年(6)

2023年(8)

2022年(2)

2021年(2)

2020年(29)

2019年(11)

2018年(23)

2017年(41)

2016年(76)

2015年(23)

我的朋友
最近访客

分类: LINUX

2017-05-27 18:54:50

uboot-1.1.6 

#set machid 0456     这是用来设置mach id的
/*
 * Configurable monitor commands definitions have been moved
 * to include/cmd_confdefs.h
 */
include/command.h
如果要把一个变量放入.u_boot_cmd段,需要通过宏U_BOOOT_CMD实现。宏的定义如下:
#define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))
#ifdef  CFG_LONGHELP
#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}
#else /* no long help info */
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}
#endif /* CFG_LONGHELP */

  ##”与“#”都是预编译操作符,“##”有字符串连接的功能,“#”表示后面紧接着的是一个字符串。

#define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))

其中,unused表示该函数或变量可能不使用,这个属性可以避免编译器产生警告信息。

凡通过U_BOOT_CMD定义的cmd_tbl_t变量会全部被放在.u_boot_cmd段当中。这也是在你写的.c文件的末尾必须要写的,为了完成注册这个动作。

在文件u-boot.lds中有如下定义:

      __u_boot_cmd_start = .;

      .u_boot_cmd : { *(.u_boot_cmd) }

      __u_boot_cmd_end = .;

该段的含义为定义一个新段.u_boot_cmd。__u_boot_cmd_start为该段的第一个符号;__u_boot_cmd_end为该段的最后一个符号。 



/*
 * Monitor Command Table
 */

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; 


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
common/command.c
Uboot中所有命令都是存放在这个特殊段中的。当用户输入一个命令时(需要与定义时的name变量同名),会在函数find_cmd中从__u_boot_cmd_start开始循环匹配,匹配到后就执行对应变量中的cmd项;如果直到__u_boot_cmd_end也没有发现,则匹配失败。
/***************************************************************************
 * 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);
 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 */
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
common/main.c
/****************************************************************************
 * returns:
 * 1  - command executed, repeatable
 * 0  - command executed but not repeatable, interrupted commands are
 *      always considered not repeatable
 * -1 - not executed (unrecognized, bootd recursion or too many args)
 *           (If cmd is NULL or "" or longer than CFG_CBSIZE-1 it is
 *           considered unrecognized)
 *
 * WARNING:
 *
 * We must create a temporary copy of the command since the command we get
 * may be the result from getenv(), which returns a pointer directly to
 * the environment data, which may change magicly when the command we run
 * creates or modifies environment variables (like "bootp" does).
 */
int run_command (const char *cmd, int flag)
{
//例如        run_command("nand read 0x40008000 0x400000 0x300000",0);
//        run_command(
"bootm 0x40008000",0);
 cmd_tbl_t *cmdtp;
 char cmdbuf[CFG_CBSIZE]; /* working copy of cmd  */
 char *token;   /* start of token in cmdbuf */
 char *sep;   /* end of token (separator) in cmdbuf */
 char finaltoken[CFG_CBSIZE];
 char *str = cmdbuf;
 char *argv[CFG_MAXARGS + 1]; /* NULL terminated */
 int argc, inquotes;
 int repeatable = 1;
 int rc = 0;
#ifdef DEBUG_PARSER
 printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
 puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */
 puts ("\"\n");
#endif
 clear_ctrlc();  /* forget any previous Control C */
 if (!cmd || !*cmd) {
  return -1; /* empty command */
 }
 if (strlen(cmd) >= CFG_CBSIZE) {
  puts ("## Command too long!\n");
  return -1;
 }
 strcpy (cmdbuf, cmd);
 /* Process separators and check for invalid
  * repeatable commands
  */
#ifdef DEBUG_PARSER
 printf ("[PROCESS_SEPARATORS] %s\n", cmd);
#endif
 while (*str) {
  /*
   * Find separator, or string end
   * Allow simple escape of ';' by writing "\;"
   */
  for (inquotes = 0, sep = str; *sep; sep++) {
   if ((*sep=='\'') &&
       (*(sep-1) != '\\'))
    inquotes=!inquotes;
   if (!inquotes &&
       (*sep == ';') && /* separator  */
       ( sep != str) && /* past string start */
       (*(sep-1) != '\\')) /* and NOT escaped */
    break;
  }
  /*
   * Limit the token to data between separators
   */
  token = str;
  if (*sep) {
   str = sep + 1; /* start of command for next pass */
   *sep = '\0';
  }
  else
   str = sep; /* no more commands for next pass */
#ifdef DEBUG_PARSER
  printf ("token: \"%s\"\n", token);
#endif
  /* find macros in this token and replace them */
  process_macros (token, finaltoken);
  /* Extract arguments */
  if ((argc = parse_line (finaltoken, argv)) == 0) {
   rc = -1; /* no command at all */
   continue;
  }
  /* Look up command in command table */
//在表中查找
名字为setenv的结构体,
//找到名字相同的cmd_tbl_t结构体,就可以调用cmdtp->cmd 执行动作
if ((cmdtp = find_cmd(argv[0])) == NULL) {
   printf ("Unknown command '%s' - try 'help'\n", argv[0]);
   rc = -1; /* give up after bad command */
   continue;
  }
  /* found - check max args */
  if (argc > cmdtp->maxargs) {
   printf ("Usage:\n%s\n", cmdtp->usage);
   rc = -1;
   continue;
  }
#if (CONFIG_COMMANDS & CFG_CMD_BOOTD)
  /* avoid "bootd" recursion */
  if (cmdtp->cmd == do_bootd) {
#ifdef DEBUG_PARSER
   printf ("[%s]\n", finaltoken);
#endif
   if (flag & CMD_FLAG_BOOTD) {
    puts ("'bootd' recursion detected\n");
    rc = -1;
    continue;
   } else {
    flag |= CMD_FLAG_BOOTD;
   }
  }
#endif /* CFG_CMD_BOOTD */
  /* OK - call function to do the command */
  if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {//调用命令函数
   rc = -1;
  }
  repeatable &= cmdtp->repeatable;
  /* Did the user stop this? */
  if (had_ctrlc ())
   return 0; /* if stopped then not repeatable */
 }
 return rc ? rc : repeatable;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

common/cmd_nvedit.c
U_BOOT_CMD(
 saveenv, 1, 0, do_saveenv,
 "saveenv - save environment variables to persistent storage\n",
 NULL
);
///////////////////////
common/cmd_nvedit.c
U_BOOT_CMD(
 setenv, CFG_MAXARGS, 0, do_setenv,
 "setenv  - set environment variables\n",
 "name value ...\n"
 "    - set environment variable 'name' to 'value ...'\n"
 "setenv name\n"
 "    - delete environment variable 'name'\n"
);
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
一般run_command("usb start", 0);那么是调用cmd_usb.c里的do_usb
run_command("fatload usb 0 0x82000000 ESHOW", 0)  ,common/cmd_fat.c ,do_fat_fsload函数

U_BOOT_CMD(
    usb,    5,    1,    do_usb,
    "USB sub-system",
    "reset - reset (rescan) USB controller\n"
    "usb stop [f]  - stop USB [f]=force stop\n"
    "usb tree  - show USB device tree\n"
    "usb info [dev] - show available USB devices\n"
    "usb storage  - show details of USB storage devices\n"
    "usb dev [dev] - show or set current USB storage device\n"
    "usb part [dev] - print partition table of one or all USB storage"
    " devices\n"
    "usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
    "    to memory address `addr'"
    "usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n"
    "    from memory address `addr'"
);
///////////////////////////////////////////////////////////////////////////////////////////


阅读(3283) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~