uboot命令的执行过程是什么

描述

U-boot是通过执行u-boot提供的命令来加载Linux内核的,其中命令bootm的功能即为从memory启动Linux内核映像文件。

在讲解bootm加载内核之前,先来看看u-boot中u-boot命令的执行过程。

1、u-boot命令的执行过程

在u-boot命令执行到最后时,开始进入命令循环,等待用户输入命令和处理命令,这是通过循环调用main_loop()函数来实现的,main_loop函数的主要代码如下所示。

len=readline (CONFIG_SYS_PROMPT);
                      flag=0;  /*assume no special flags for now*/
                      if (len > 0)
                          strcpy (lastcommand, console_buffer);
                      else if (len == 0)
                          flag —= CMD_FLAG_REPEAT;
                      rc=run_command (lastcommand, flag);

Main_loop函数从串口终端读入用户输入的要执行的命令行(包括命令和参数),然后调用run_command函数来执行用户输入的命令行。

下面分析 run_command函数的主要工作流程 ,run_command的主要源码如下所示。

strcpy(cmdbuf, cmd);
               /*Extract arguments*/
                           if((argc=parse_line(finaltoken, argv))==0){
                               rc=-1;   /*no command at all*/
                               continue;
                           }
                          /*Look up command in command table*/
                           if((cmdtp=find_cmd(argv[0]))==NULL){
                               printf("Unknown command' %s' -try' help' n", argv[0]);
                               rc=-1;   /*give up after bad command*/
                               continue;
                           }
                          /*OK-call function to do the command*/
                           if((cmdtp- >cmd)(cmdtp, flag, argc, argv)! =0){
                               rc=-1;
                           }

从代码中可以看出,run_command函数通过调用函数parse_line分析出该命令行所对应的参数个数argc和参数指针数组*argv[ ],

其中 argv[0]中保存的是u-boot命令名字符串 ,接着调用 函数find_cmd

函数 根据命令名在u-boot命令列表中找到该命令对应的u-boot命令结构体cmd_tbl_t所在的地址

找到该u-boot命令对应的命令结构体后,就可以调用 该结构体中的u-boot命令对应的执行函数来完成该u-boot命令的功能 ,这样一个u-boot命令就执行完成了。

下面再来看看u-boot命令结构体cmd_tbl_t及其定义过程和存放的位置。

U-boot命令结构体cmd_tbl_t定义如下所示。

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     CONFIG_SYS_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
                };

Cmd_tbl_t结构用来保存u-boot命令的相关信息, 包括命令名称、对应的执行函数、使用说明、帮助信息等

每一条u-boot命令都对应一个cmd_tbl_t结构体变量 ,在u-boot中是通过宏U_BOOT_CMD来实现cmd_tbl_t结构体变量的定义和初始化的。

例如,bootm命令对应U_BOOT_CMD调用,代码如下所示。

U_BOOT_CMD(
                  bootm,    CONFIG_SYS_MAXARGS,     1,    do_bootm,
                  "boot application image from memory",
                  "[addr[arg...]]n     -boot application image stored in memoryn"
                  "tpassing arguments ' arg ...' ; when booting a Linux kernel, n"
                  "t' arg' can be the address of an initrd imagen");

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宏就定义了cmd_tbl_t类型的结构体变量,变量名为**__u_boot_cmd_bootm**,同时用U_BOOT_CMD宏中的参数对cmd_tbl_t结构体中的每个成员进行初始化。

Struct_Section也是一个宏定义,定义如下所示。

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

Struct_Section定义了结构体变量的段属性,cmd_tbl_t类型的结构体变量链接时全部链接到u_boot_cmd段中,可以查看u-boot.lds文件对u_boot_cmd段位置的安排。

(这里我们应该有想到,关于uboot_cmd,我们可以外界输入,内部的肯定也有提前预设的值,比如启动内核这些。如果在这个启动延时的过程中不进行输入,那么就会去执行这些默认的命令。)

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分