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,我们可以外界输入,内部的肯定也有提前预设的值,比如启动内核这些。如果在这个启动延时的过程中不进行输入,那么就会去执行这些默认的命令。)
-
内核
+关注
关注
3文章
1372浏览量
40289 -
Linux
+关注
关注
87文章
11304浏览量
209497 -
函数
+关注
关注
3文章
4331浏览量
62618 -
Uboot
+关注
关注
4文章
125浏览量
28230
发布评论请先 登录
相关推荐
评论