U-boot是通過執(zhí)行u-boot提供的命令來加載Linux內(nèi)核的,其中命令bootm的功能即為從memory啟動(dòng)Linux內(nèi)核映像文件。
在講解bootm加載內(nèi)核之前,先來看看u-boot中u-boot命令的執(zhí)行過程。
1、u-boot命令的執(zhí)行過程
在u-boot命令執(zhí)行到最后時(shí),開始進(jìn)入命令循環(huán),等待用戶輸入命令和處理命令,這是通過循環(huán)調(diào)用main_loop()函數(shù)來實(shí)現(xiàn)的,main_loop函數(shù)的主要代碼如下所示。
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函數(shù)從串口終端讀入用戶輸入的要執(zhí)行的命令行(包括命令和參數(shù)),然后調(diào)用run_command函數(shù)來執(zhí)行用戶輸入的命令行。
下面分析 run_command函數(shù)的主要工作流程 ,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函數(shù)通過調(diào)用函數(shù)parse_line分析出該命令行所對(duì)應(yīng)的參數(shù)個(gè)數(shù)argc和參數(shù)指針數(shù)組*argv[ ],
其中 argv[0]中保存的是u-boot命令名字符串 ,接著調(diào)用 函數(shù)find_cmd ,
函數(shù) 根據(jù)命令名在u-boot命令列表中找到該命令對(duì)應(yīng)的u-boot命令結(jié)構(gòu)體cmd_tbl_t所在的地址 ,
找到該u-boot命令對(duì)應(yīng)的命令結(jié)構(gòu)體后,就可以調(diào)用 該結(jié)構(gòu)體中的u-boot命令對(duì)應(yīng)的執(zhí)行函數(shù)來完成該u-boot命令的功能 ,這樣一個(gè)u-boot命令就執(zhí)行完成了。
下面再來看看u-boot命令結(jié)構(gòu)體cmd_tbl_t及其定義過程和存放的位置。
U-boot命令結(jié)構(gòu)體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結(jié)構(gòu)用來保存u-boot命令的相關(guān)信息, 包括命令名稱、對(duì)應(yīng)的執(zhí)行函數(shù)、使用說明、幫助信息等 。
每一條u-boot命令都對(duì)應(yīng)一個(gè)cmd_tbl_t結(jié)構(gòu)體變量 ,在u-boot中是通過宏U_BOOT_CMD來實(shí)現(xiàn)cmd_tbl_t結(jié)構(gòu)體變量的定義和初始化的。
例如,bootm命令對(duì)應(yīng)U_BOOT_CMD調(diào)用,代碼如下所示。
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類型的結(jié)構(gòu)體變量,變量名為**__u_boot_cmd_bootm**,同時(shí)用U_BOOT_CMD宏中的參數(shù)對(duì)cmd_tbl_t結(jié)構(gòu)體中的每個(gè)成員進(jìn)行初始化。
Struct_Section也是一個(gè)宏定義,定義如下所示。
#define Struct_Section __attribute__((unused, section(".u_boot_cmd")))
Struct_Section定義了結(jié)構(gòu)體變量的段屬性,cmd_tbl_t類型的結(jié)構(gòu)體變量鏈接時(shí)全部鏈接到u_boot_cmd段中,可以查看u-boot.lds文件對(duì)u_boot_cmd段位置的安排。
(這里我們應(yīng)該有想到,關(guān)于uboot_cmd,我們可以外界輸入,內(nèi)部的肯定也有提前預(yù)設(shè)的值,比如啟動(dòng)內(nèi)核這些。如果在這個(gè)啟動(dòng)延時(shí)的過程中不進(jìn)行輸入,那么就會(huì)去執(zhí)行這些默認(rèn)的命令。)
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1372瀏覽量
40276 -
Linux
+關(guān)注
關(guān)注
87文章
11292瀏覽量
209323 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4327瀏覽量
62569 -
Uboot
+關(guān)注
關(guān)注
4文章
125瀏覽量
28214
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論