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文章
1382瀏覽量
40422 -
Linux
+關注
關注
87文章
11345瀏覽量
210387 -
函數
+關注
關注
3文章
4346瀏覽量
62968 -
Uboot
+關注
關注
4文章
125瀏覽量
28348
發布評論請先 登錄
相關推薦
評論