當(dāng)前位置:首頁 > 芯聞號(hào) > 充電吧
[導(dǎo)讀]當(dāng)我們?cè)诳刂婆_(tái)的時(shí)候,輸入boot可以啟動(dòng)Linux內(nèi)核,那么我們以boot為例子來解析一下uboot命令的執(zhí)行過程,為下一步分析uboot怎樣啟動(dòng)Linux來做準(zhǔn)備。 一、我們搜索boot命令

當(dāng)我們?cè)诳刂婆_(tái)的時(shí)候,輸入boot可以啟動(dòng)Linux內(nèi)核,那么我們以boot為例子來解析一下uboot命令的執(zhí)行過程,為下一步分析uboot怎樣啟動(dòng)Linux來做準(zhǔn)備。 一、我們搜索boot命令

grep -wnR "boot" common
得到:common/cmd_bootm.c:1162: boot, 1, 1, do_bootd,

打開common/cmd_bootm.c 文件
int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
    int rcode = 0;
#ifndef CFG_HUSH_PARSER
    if (run_command (getenv ("bootcmd"), flag) < 0) rcode = 1;
#else
    if (parse_string_outer(getenv("bootcmd"),
        FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0 ) rcode = 1;
#endif
    return rcode;
}

U_BOOT_CMD(
    boot,   1,  1,  do_bootd,
    "boot    - boot default, i.e., run 'bootcmd'n",
    NULL
);
其中U_BOOT_CMD命令格式如下:

U_BOOT_CMD(name,maxargs,repeatable,command,"usage","help")

 各個(gè)參數(shù)的意義如下:

   name:命令名,非字符串,但在U_BOOT_CMD中用“#”符號(hào)轉(zhuǎn)化為字符串
   maxargs:命令的最大參數(shù)個(gè)數(shù)
   repeatable:是否自動(dòng)重復(fù)(按Enter鍵是否會(huì)重復(fù)執(zhí)行)
   command:該命令對(duì)應(yīng)的響應(yīng)函數(shù)指針
   usage:簡短的使用說明(字符串)
   help:較詳細(xì)的使用說明(字符串)
二、U_BOOT_CMD宏分析 ① U_BOOT_CMD宏在include/command.h中定義:
#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}

“##”“#”都是預(yù)編譯操作符,“##”有字符串連接的功能,“#”表示后面緊接著的是一個(gè)字符串。

② 其中的cmd_tbl_t在include/command.h中定義如下:
struct cmd_tbl_s {
       char       *name;          /* 命令名 */
       int          maxargs;       /* 最大參數(shù)個(gè)數(shù) */
       int          repeatable;    /* 是否自動(dòng)重復(fù) */
       int          (*cmd)(struct cmd_tbl_s *, int, int, char *[]);  /*  響應(yīng)函數(shù) */
       char       *usage;         /* 簡短的幫助信息 */
#ifdef    CONFIG_SYS_LONGHELP
       char              *help;           /*  較詳細(xì)的幫助信息 */
#endif
#ifdef CONFIG_AUTO_COMPLETE
       /* 自動(dòng)補(bǔ)全參數(shù) */
       int          (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);
#endif
};

typedef struct cmd_tbl_s  cmd_tbl_t;
extern cmd_tbl_t  __u_boot_cmd_start;
extern cmd_tbl_t  __u_boot_cmd_end;

一個(gè)cmd_tbl_t結(jié)構(gòu)體變量包含了調(diào)用一條命令的所需要的信息。

③ 其中Struct_Section在include/command.h中定義如下:
 #define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))

凡是帶有attribute ((unused,section (“.u_boot_cmd”))屬性聲明的變量都將被存放在”.u_boot_cmd”段中,并且即使該變量沒有在代碼中顯式的使用編譯器也不產(chǎn)生警告信息。

在u-Boot連接腳本boardsmdk2410u-boot.lds中定義了”.u_boot_cmd”段:
. = .;
__u_boot_cmd_start = .;          /*將 __u_boot_cmd_start指定為當(dāng)前地址 */
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;           /*  將__u_boot_cmd_end指定為當(dāng)前地址  */
這表明帶有“.u_boot_cmd”聲明的函數(shù)或變量將存儲(chǔ)在“u_boot_cmd”段。 這樣只要將u-boot所有命令對(duì)應(yīng)的cmd_tbl_t變量加上“.u_boot_cmd”聲明,編譯器就會(huì)自動(dòng)將其放在“u_boot_cmd”段,查找cmd_tbl_t變量時(shí)只要在__u_boot_cmd_start與__u_boot_cmd_end之間查找就可以了。 三、boot命令宏展開 因此“boot”命令的定義經(jīng)過宏展開后如下:

    cmd_tbl_t __u_boot_cmd_boot __attribute__ ((unused,section (".u_boot_cmd"))) = {boot, 1, 1, do_bootd, "boot    - boot default, i.e., run 'bootcmd'n", " NULL"}
int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
    int rcode = 0;
#ifndef CFG_HUSH_PARSER
    if (run_command (getenv ("bootcmd"), flag) < 0) rcode = 1;
#else
    if (parse_string_outer(getenv("bootcmd"),
        FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0 ) rcode = 1;
#endif
    return rcode;
}
四、run_command分析 u-boot啟動(dòng)第二階段最后跳到main_loop函數(shù)中循環(huán),
        s = getenv ("bootcmd");
    if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
        ......
        run_command (s, 0);
        ......
        }
從main_loop中我們知道,如果bootdelay時(shí)間內(nèi)未按下按鍵則啟動(dòng)Linux內(nèi)核,按下按鍵則進(jìn)入uboot命令行等待用戶輸入命令。 用戶輸入命令則調(diào)取run_command函數(shù),在該函數(shù)中有下面幾個(gè)比較重要的點(diǎn): 1. 從注釋我們很容易知道這段代碼是在對(duì)命令進(jìn)行分離,并且u-boot支持’;’分離命令。
        /*
         * Find separator, or string end
         * Allow simple escape of ';' by writing ";"
         */
        for (inquotes = 0, sep = str; *sep; sep++) {
            if ((*sep==''') &&
                (*(sep-1) != '\'))
                inquotes=!inquotes;

            if (!inquotes &&
                (*sep == ';') &&    /* separator        */
                ( sep != str) &&    /* past string start    */
                (*(sep-1) != '\')) /* and NOT escaped  */
                break;
        }
2. 分離參數(shù)
        /* Extract arguments */
        if ((argc = parse_line (finaltoken, argv)) == 0) {
            rc = -1;    /* no command at all */
            continue;
        }
3. 用第一個(gè)參數(shù)argv[0]在命令列表中尋找對(duì)應(yīng)的命令,并返回一個(gè)cmd_tbl_t類型的實(shí)例。我們可以猜到這個(gè)結(jié)構(gòu)體應(yīng)該保函了有關(guān)命令的一系列內(nèi)容。
        /* 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;
        }
在common/command.c 中查看find_cmd函數(shù)
/*__u_boot_cmd_start與__u_boot_cmd_end間查找命令,并返回cmdtp->name命令的cmd_tbl_t結(jié)構(gòu)。*/
cmd_tbl_t *cmdtp;
    cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start;    /*Init value */
    const char *p;
    int len;
    int n_found = 0;

    /*
     * Some commands allow length modifiers (like "cp.b");
     * compare command name only until first dot.
     */
    len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);

    for (cmdtp = &__u_boot_cmd_start;
         cmdtp != &__u_boot_cmd_end;
         cmdtp++) {
        if (strncmp (cmd, cmdtp->name, len) == 0) {
            if (len == strlen (cmdtp->name))
                return cmdtp;   /* full match */

            cmdtp_temp = cmdtp; /* abbreviated command ? */
            n_found++;
        }
    }
五、總結(jié)命令執(zhí)行過程 ① 在u-boot控制臺(tái)中輸入“boot”命令執(zhí)行時(shí),u-boot控制臺(tái)接收輸入的字符串“boot”,傳遞給run_command函數(shù)。 ② run_command函數(shù)調(diào)用common/command.c中實(shí)現(xiàn)的find_cmd函數(shù)在__u_boot_cmd_start與__u_boot_cmd_end間查找命令,并返回boot命令的cmd_tbl_t結(jié)構(gòu)。 ③ 然后run_command函數(shù)使用返回的cmd_tbl_t結(jié)構(gòu)中的函數(shù)指針調(diào)用boot命令的響應(yīng)函數(shù)do_bootd,從而完成了命令的執(zhí)行。 六、自制u-boot命令

① 首先我們?cè)趗-boot的common目錄下增加一個(gè)cmd_czg.c文件 。 復(fù)制cmd_bootm.c中的頭文件到cmd_czg.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
②、③定義命令和操作函數(shù)
#include 
#include 
#include 
#include 
#include 
#include 
#include 
int do_czg (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
        int i;
        for(i=0;i
④ 修改common下面的makefile文件,

參考Makefile中其他文件的定義,加入一句

COBJS += cmd_czg.o
⑤ 清除配置編譯u-boot并燒錄
make distclean
make 100ask24x0_config
make

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉