Chinaunix首页 | 论坛 | 博客
  • 博客访问: 96338
  • 博文数量: 38
  • 博客积分: 1640
  • 博客等级: 上尉
  • 技术积分: 415
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-25 08:02
文章分类

全部博文(38)

文章存档

2011年(5)

2010年(19)

2009年(14)

我的朋友

分类: LINUX

2009-10-27 20:08:45

 
关于U-boot中命令相关的编程:

1、命令相关的函数和定义
   @main_loop:这个函数里有太多编译选项,对于smdk2410,去掉所有选项后等效下面的程序
   void main_loop()
    {
     static char lastcommand[CFG_CBSIZE] = { 0, };
     int len;
     int rc = 1;
     int flag;
    char *s;
     int bootdelay;
     s = getenv ("bootdelay");   //自动启动内核等待延时
     bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
   
     debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
     s = getenv ("bootcmd");   //取得环境中设置的启动命令行
     debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "");
   
     if (bootdelay >= 0 && s && !abortboot (bootdelay))
     {
      run_command (s, 0);//执行启动命令行,smdk2410.h中没有定义CONFIG_BOOTCOMMAND,所以没有命令执行。
     }
    
     for (;;) {
     len = readline(CFG_PROMPT);//读取键入的命令行到console_buffer
   
      flag = 0; /* assume no special flags for now */
      if (len > 0)
       strcpy (lastcommand, console_buffer);//拷贝命令行到lastcommand.
      else if (len == 0)
       flag |= CMD_FLAG_REPEAT;
       if (len == -1)
       puts ("\n");
      else
       rc = run_command (lastcommand, flag); //执行这个命令行。
   
      if (rc <= 0) {
       /* invalid command or not repeatable, forget it */
       lastcommand[0] = 0;
     }
    }
 @run_comman();在命令table中查找匹配的命令名称,得到对应命令结构体变量指针,以解析得到的参数调用其处理函数执行命令。
    @命令结构构体类型定义:command.h中,
    struct cmd_tbl_s {
     char   *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;


    //定义section属性的结构体。编译的时候会单独生成一个名为.u_boot_cmd的section段。
    #define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))


    //这个宏定义一个命令结构体变量。并用name,maxargs,rep,cmd,usage,help初始化各个域。
    #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、在u-boot中,如何添加一个命令:
     1)CFG_CMD_* 命令选项位标志。在include/cmd_confdefs.h 中定义。
     每个板子的配置文件(如include/config/smdk2410.h)中都可以定义u-boot
     需要的命令,如果要添加一个命令,必须添加相应的命令选项。如下:
      #define CONFIG_COMMANDS \
     (CONFIG_CMD_DFL | \
     CFG_CMD_CACHE | \
     /*CFG_CMD_NAND |*/ \
     /*CFG_CMD_EEPROM |*/ \
     /*CFG_CMD_I2C |*/ \
     /*CFG_CMD_USB |*/ \
     CFG_CMD_REGINFO | \
     CFG_CMD_DATE | \
     CFG_CMD_ELF)
     定义这个选项主要是为了编译命令需要的源文件,大部分命令都在common文件夹下对应一个源文件
     cmd_*.c ,如cmd_cache.c实现cache命令。 文件开头就有一行编译条件:
     #if(CONFIG_COMMANDS&CFG_CMD_CACHE)
     也就是说,如果配置头文件中CONFIG_COMMANDS不或上相应命令的选项,这里就不会被编译。
   2)定义命令结构体变量,如:
     U_BOOT_CMD(
          dcache,   2,   1,     do_dcache,
          "dcache - enable or disable data cache\n",
          "[on, off]\n"
          "    - enable or disable data (writethrough) cache\n"
         );
 其实就是定义了一个cmd_tbl_t类型的结构体变量,这个结构体变量名为__u_boot_cmd_dcache。
     其中变量的五个域初始化为括号的内容。分别指明了命令名,参数个数,重复数,执行命令的函数,命令提示。
     每个命令都对应这样一个变量,同时这个结构体变量的section属性为.u_boot_cmd.也就是说每个变量编译结束
     在目标文件中都会有一个.u_boot_cmd的section.一个section是连接时的一个输入段,如.text,.bss,.data等都是section名。
     最后由链接程序把所有的.u_boot_cmd段连接在一起,这样就组成了一个命令结构体数组。
     u-boot.lds中相应脚本如下:
       . = .;
       __u_boot_cmd_start = .;
       .u_boot_cmd : { *(.u_boot_cmd) }
       __u_boot_cmd_end = .;
     可以看到所有的命令结构体变量集中在__u_boot_cmd_start开始到__u_boot_cmd_end结束的连续地址范围内,
     这样形成一个cmd_tbl_t类型的数组,run_command函数就是在这个数组中查找命令的。
   3)实现命令处理函数。命令处理函数的格式:
    void function (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

总体来说,如果要实现自己的命令,应该在include/com_confdefs.h中定义一个命令选项标志位。
    在板子的配置文件中添加命令自己的选项。按照u-boot的风格,可以在common/下面添加自己的cmd_*.c,并且定义自己的命令结构体变量,如U_BOOT_CMD(
          mycommand,   2,   1,     do_mycommand,
          "my command!\n",
          "...\n"
          " ..\n"
         );

然后实现自己的命令处理函数do_mycommand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])。

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