中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

S5PV210-uboot源碼分析-uboot命令體系

發布時間:2020-07-11 22:19:33 來源:網絡 閱讀:406 作者:小溢 欄目:開發技術




8、1、uboot的命令體系

1、使用uboot命令

2、uboot實現命令體系的代碼uboot/commond/cmd_xxx.c中,有若干個.c文件和命令體系有關。還有個main.c也是跟命令體系有關的。

3、每個命令對應一個函數

(1)uboot中的每一個命令都對應了一個函數在背后,這就是uboot來實現命令體系的一種方法。和我們在裸機中寫的shell中實現的方法其實是一樣的。

(2)我們要找到每一個命令背后所對應的那個函數,而且要分析每一個函數和每一個命令是怎么對應起來的。

4、命令的參數以argc&argv的方式來傳遞給函數

(1)有些uboot的命令還支持傳參,也就是說命令背后對應的函數接受的參數列表中有argc和argv這兩個參數。然后命令體系會吧我們執行命令時的命令加參數,以argc和argv的方式傳遞給執行命令的函數。

(2)run_command函數就是用來執行命令的函數


8、2、uboot命令解析和執行過程分析

1、從main_loop函數說起

(1)我們在uboot的第二階段,也就是start_armboot這個函數在初始化了一些板上的硬件后,最后進入到了死循環,這個死循環不斷的執行一個函數叫做main_loop,這個函數的其實就是在不斷獲取我們輸入到uboot命令行中的命令,解析這個命令,執行這個命令。直到執行了bootm 這個命令去啟動內核。


8、3、run_command函數詳解

1、控制命令獲取



2、解析命令

(1)paser_line函數用來解析,如將(md 0x30001000 10)把argv[0] = "md" argv[1] = "0x30001000" argv[2] = "10"


3、命令集中查找命令

(1)find_cmd(argv[0])函數就是去命令集合找有沒有這個argv[0]中的那個命令。


4、執行命令

(1)最后用函數指針的形式調用了這個命令所對應的函數


總結:在獲取命令和解析命令和執行命令的過程中,最關鍵的部分就是find_cmd這個函數是如何通過我們輸入的命令找到這個在uboot命令體系中的命令的。同時,關鍵的還有,uboot是如何注冊一個命令的,存儲,管理,索引一個命令的,索引的過程就是find_cmd這個查找的過程。


8、4、uboot如何處理命令集1

1、可能的管理方式

(1)數組:比如可以用結構體數組的方式,數組中的每一個元素都是一個結構體,每一個結構體表示一個命令的所有信息

(2)鏈表:比如也可以用鏈表,鏈表的每一個節點的data,就是一個命令的結構體,這個結構體中包含了命令的所有信息。壞處是內存開銷變大了,因為需要存放頭指針和尾指針,并且代碼的復雜度變大了,程序運行的效率因此會有所降低,但是靈活性相當于數組來說,卻好了很多,因為數組的大小都是直接給定的,不靈活。

(3)有第三種嗎?uboot實際上沒有用前兩種的方式來實現這個命令體系。而是用了一種新的方式來實現了這個功能。


2、命令結構體cmd_tpl_t

struct cmd_tbl_s {

char *name; /* Command Name */

int maxargs; /* maximum number of arguments */

int repeatable; /* autorepeat allowed? 1:OK 0:NO *///命令輸完后回車一遍后,在回車可以繼續上一次的命令

/* Implementation function */

int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);

char *usage; /* Usage message (short) *///簡單說明

#ifdef CFG_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

};


typedef struct cmd_tbl_s cmd_tbl_t;


(1)name:命令的名稱,字符串格式的

(2)maxargs:命令所能接收的參數的最大個數

(3)repeatable:命令是否能夠重復執行,就是直接按回車能否執行上一次輸入的命令

(4)cmd:函數指針,命令所對應的那個函數的函數指針。

(5)usage:使用信息,簡單的使用信息說明

(6)help:使用信息,詳細的使用信息說明

(7)complete:函數指針,指向這個命令的自動補全函數

總結:uboot的命令體系在工作的時候,一個命令對應一個這個cmd_tbl_t結構體的實例(實例化),uboot需要多少個命令就需要多少個cmd_tbl_t這個結構體的實例。uboot的命令體系把這些結構體實例管理起來,當用戶輸入一個命令的時候,uboot會去這些結構體實例中查找(查找方法和管理方法有關)。如果找到則執行這個實例當中的cmd函數指針去執行命令。如果沒有找到則提示命令未知。


3、uboot實現命令管理的思路

(1)填充一個結構體實例構成一個命令

(2)給命令結構體附加一個特定的段屬性(用戶自定義段),鏈接時鏈接器就會將有該段屬性的內容鏈接在一起排列(挨著的,不會夾雜著其他東西,也不會丟掉任何一個帶有這種段屬性的,但是順序是亂序的)。(鏈接完成后,最后都會在u-boot.bin這個鏡像中)。

(3)uboot在重定位的時候,將該段屬性整片加載到DDR中。(其實分析開來,加載到DDR中的uboot鏡像的帶有特定段屬性的這一段是一個命令結構體的集合,有點像一個結構體數組,不一樣的是,我們在寫完這些結構體實例后,寫了多少個結構體實例,鏈接器就會鏈接多少個,最后形成鏡像后,我們直接重定位到DDR中,這樣就彌補了數組的不靈活性)

(4)段起始地址和結束地址(鏈接地址,定義在u-boot.lds中)決定了這些命令的開始和結束地址。



8、5、uboot如何處理命令集2


1、1、uboot命令定義具體實現分析

1、1、1、U_BOOT_CMD宏基本分析

1、這個宏在uboot/common/commond.h中的93行到99行定義


#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}


(1)這個宏接接收六個參數。宏體cmd_tbl_t是命令的結構體類型,用這個類型定義了一個變量叫__u_boot_cmd_##name

其中##name,是gcc支持的,##name將來會被宏傳遞進去的name這個參數替代,也就是##name就是name這個參數。

(2)Struct_Section 是由這個宏定義的

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

(2(1))_attribute__ ((unused,section (".u_boot_cmd")))是gcc中的一種擴展語法,給賦予屬性,目的就是給前面的變量賦予一個段屬性(.u_boot_cmd)就是把##name這個變量放在了這個.u_boot_cmd這個段上。

(3) = {#name, maxargs, rep, cmd, usage, help} 就是將這個被放在用戶自定義段(.u_boot_cmd)的結構體變量##name進行初始化,值就是宏傳參過來的六個參數。

其中的參數有一個#name,這個參數前面有個#號的意思就是,將傳進來的東西轉換成字符串,因為結構體成員的第一個是一個字符串。

(4)鏈接腳本:鏈接腳本中,有這個段的起始地址和結束地址。在u-boot.lds中


總結:這個宏的最終實現的就是填充一個命令,并且將這個命令附加了一個段屬性。將來屬于這同一屬性的東西,鏈接器在鏈接的時候,就會鏈接在一起進行排列。


1、1、2、find_cmd函數詳解

(1)find_cmd函數的任務就是從uboot的命令集中,查找是否有這個命令。如果找到,就返回這個命令結構體的指針,如果沒找到,返回NULL。

(2)函數中的,__u_boot_cmd_start,是在commond.h中聲明的,是在u-boot.lds中定義的。

cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start;

意思就是將命令集在DDR中的鏈接處的首地址給cmdtp_temp指針,讓這個指針指向這個地址。

(3)這個函數實現查找命令的思路就是,使用了一個for循環的方式,知道命令集的鏈接時的首地址,命令集鏈接時的結束地址是這個for循環的終止條件,這個命令結構體++,來查詢這一段命令集的所有命令,看哪一個名字和長度是相同的。,找到后返回這個命令的結構體指針。




8、6、uboot中自定義命令

1、在已有的c文件中直接添加命令

(1)在uboot/common/command.c中添加

在已有的.c文件中添加命令比較簡單,直接使用U_BOOT_CMD宏添加就行,相應的我們也要為我們添加的命令,添加一個對應的命令所以執行的函數do_xxx。

(2)添加完了要重新make distclean,和配置編譯工程,在燒錄u-boot.bin,運行就可以了查找這個命令了

(3)也可以用argc和argv來驗證函數的傳參,你也可以根據這些傳參做一些應該做的事情



2、uboot中自建c文件添加一個命令

(1)在uboot/common目錄下新建一個.c文件,名字以cmd_為開頭,如果你的文件的名字叫做cmd_why.c,那么將來對應的命令名就叫做why,對應的函數就叫do_why函數(這是一種命名規范,別人添加命令的時候,是這樣的,所以我們也要按照這樣的方式去添加),然后在c文件中添加U_BOOT_CMD宏和對應的函數。注意:頭文件要包含。

(2)還要在uboot/common中的makefile中添加這個.o文件,目的是就是讓我們寫的文件能夠在makefile中編譯,能鏈接進去

(3)重新make distclean , make x210_sd_config , make


















向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

济源市| 靖安县| 茂名市| 三都| 乐业县| 铁岭县| 美姑县| 辽阳县| 贵定县| 井陉县| 尉氏县| 五指山市| 莱芜市| 叙永县| 乐都县| 阜康市| 宁夏| 南宁市| 清镇市| 安陆市| 万载县| 建阳市| 平陆县| 台南县| 梅州市| 明水县| 达孜县| 上高县| 都安| 西峡县| 高陵县| 醴陵市| 天祝| 亚东县| 大连市| 桂林市| 离岛区| 友谊县| 永川市| 定安县| 视频|