uboot自定義命令
U-Boot 是一個(gè)主要用于嵌入式系統(tǒng)的引導(dǎo)加載程序,可以支持多種不同的計(jì)算機(jī)系統(tǒng)結(jié)構(gòu),包括PPC、ARM、AVR32、MIPS、x86、68k、Nios與MicroBlaze。這也是一套在GNU通用公共許可證之下發(fā)布的自由軟件。
U-Boot本質(zhì)是一個(gè)裸機(jī)程序,是一種普遍用于嵌入式系統(tǒng)中的開源的Bootloader,作用是用來引導(dǎo)操作系統(tǒng),以及給開發(fā)人員提供測試調(diào)試工具。主要負(fù)責(zé)基本硬件初始化,導(dǎo)啟動(dòng)內(nèi)核啟動(dòng)。
U-Boot命令眾多,通過uboot命令可完成系統(tǒng)環(huán)境變量設(shè)置。U-Boot本質(zhì)就是一份裸機(jī)程序,這樣可以在U-Boot命令下調(diào)試一些硬件設(shè)備問題。U-Boot命令行也是可以實(shí)現(xiàn)自動(dòng)補(bǔ)全功能。
1.uboot命令格式分析
??uboot命令存放在uboot目錄下的common目錄下。
??do_help命令功能實(shí)現(xiàn)如下:
extern cmd_tbl_t __u_boot_cmd_bdinfo; extern cmd_tbl_t __u_boot_cmd_showvar; int do_help(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { // return _do_help(&__u_boot_cmd_start, // &__u_boot_cmd_end - &__u_boot_cmd_start, // cmdtp, flag, argc, argv); return _do_help(&__u_boot_cmd_bdinfo, &__u_boot_cmd_showvar - &__u_boot_cmd_bdinfo + 1, cmdtp, flag, argc, argv); } U_BOOT_CMD( help, CONFIG_SYS_MAXARGS, 1, do_help, "print command description/usage", "\n" " - print brief description of all commands\n" "help command ...\n" " - print detailed usage of 'command'" ); /* This does not use the U_BOOT_CMD macro as ? can't be used in symbol names */ cmd_tbl_t __u_boot_cmd_question_mark Struct_Section = { "?", CONFIG_SYS_MAXARGS, 1, do_help, "alias for 'help'", #ifdef CONFIG_SYS_LONGHELP "" #endif /* CONFIG_SYS_LONGHELP */ };
U_BOOT_CMD為命令參數(shù)傳遞:
help 命令標(biāo)志符;
CONFIG_SYS_MAXARGS命令傳遞的最大參數(shù)個(gè)數(shù);
1 命令重復(fù)執(zhí)行次數(shù);
do_help命令實(shí)現(xiàn)函數(shù);
“alias for ‘help’”命令用法說明;
最后一個(gè)參數(shù)為命令用法詳細(xì)說明;
int do_help(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])函數(shù)參數(shù)說明:
cmd_tbl_t * cmdtp結(jié)構(gòu)體指針。
struct cmd_tbl_s { char *name; /* 命令名字*/ int maxargs; /*命令傳遞的最大參數(shù)個(gè)數(shù)*/ int repeatable; /*命令重復(fù)執(zhí)行次數(shù)*/ /*命令功能實(shí)現(xiàn)函數(shù)*/ int (*cmd)(struct cmd_tbl_s *, int, int, char * const []); char *usage; /*命令基本用法說明*/ #ifdef CONFIG_SYS_LONGHELP char *help; /*命令詳細(xì)用法說明*/ #endif #ifdef CONFIG_AUTO_COMPLETE /* do auto completion on the arguments */ int (*complete)(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]); #endif };
??argc 命令傳入的參數(shù)個(gè)數(shù),和main函數(shù)argc相同;
??argv 存放命令參數(shù)內(nèi)容,和main函數(shù)argv相同;
2.tiny4412下編寫uboot命令控制蜂鳴器
2.1 tiny4412開發(fā)板beep硬件接口
??配置寄存器:GPD0CON_ADDR = 0x1140_0000 + 0x00A0
2.3 參考help命令模板實(shí)現(xiàn)beep命令
#include #include /*蜂鳴器*/ #define GPD0_CON *((volatile unsigned int *)0x114000A0)//控制寄存器 #define GPD0_DAT *((volatile unsigned int *)0x114000A4)//數(shù)據(jù)寄存器 int do_beep(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { /*蜂鳴器*/ GPD0_CON&=0xfffffff0;//清除當(dāng)前GPD0_0的配置 GPD0_CON|=0x00000001;//設(shè)置為輸出模式 //beep on 或者 beep off if(argc!=2) { printf("格式:beep on/off\n"); return 0; } if(strcmp(argv[1],"on")==0)//開蜂鳴器 { GPD0_DAT|=1<<0;//開蜂鳴器 } else if(strcmp(argv[1],"off")==0)//關(guān)蜂鳴器 { GPD0_DAT&=~(1<<0);//關(guān)蜂鳴器 } return 0; } U_BOOT_CMD( beep, CONFIG_SYS_MAXARGS, 1, do_beep, "beep ", "\n" "beep用法\n" "開蜂鳴器:beep on\n" "關(guān)蜂鳴器:beep_off" );
2.4 程序編譯
??1. 將cmd_beep.c拷貝到u_boot目錄下的common目錄下
[wbyq@wbyq common]$ cp /mnt/hgfs/ubuntu/cmd_beep.c ./
??2. 修改common目錄下的Makefile文件。
[wbyq@wbyq common]$ vim Makefile

??3.在uoot頂層目錄下執(zhí)行make,重新編譯uboot
[wbyq@wbyq uboot_tiny4412-sdk1506]$ make
??4.燒寫uboot
[wbyq@wbyq uboot_tiny4412-sdk1506]$ cd sd_fuse/ [wbyq@wbyq tiny4412]$ sudo ./sd_fusing.sh /dev/sdb
??beep命令編寫成功。
??5. beep命令運(yùn)行測試
TINY4412 # beep 格式:beep on/off TINY4412 # ? beep flag=0 beep - beep Usage: beep beep用法 開蜂鳴器:beep on 關(guān)蜂鳴器:beep_off TINY4412 # beep on TINY4412 # beep off
3.分析uboot保存環(huán)境變量位置
??在Linux操作系統(tǒng)啟動(dòng)前,uboot需要完成系統(tǒng)環(huán)境變量配置。在uboot目錄下有tiny4412.h中保存的系統(tǒng)的默認(rèn)環(huán)境變量參數(shù)。
?1.當(dāng)我們修改了系統(tǒng)環(huán)境變量,執(zhí)行了saveenv命令后,則環(huán)境變量將寫入到磁盤中,接下來我們將分析一下uboot源碼中環(huán)境變量寫入磁盤的扇區(qū)位置。
在uboot命令中,并沒有直接腳cmd_save.c的函數(shù),因此,我們可以根據(jù)saveenv命令執(zhí)行后的提示信息來分析。在uboot命令行下執(zhí)行saveenv命令時(shí),會(huì)看到有輸出提示信息,這樣我們可以直接在uboot工程中搜索一下輸出信息的位置。
TINY4412 # save Saving Environment to SMDK bootable device... done



??2.接下來跳入saveenv函數(shù),查看一下該函數(shù)執(zhí)行過程。
??當(dāng)我們跳到定義處時(shí)會(huì)看到有多重位置,要想準(zhǔn)確跳轉(zhuǎn)到正確位置,我們可以再查找參考saveenv命令的后半段提示信息賦值位置。
?3.經(jīng)過查找參考我們發(fā)現(xiàn),后半段提示信息的定義位置是在env_auto.c中,而我們saveenv函數(shù)右鍵跳到定義處時(shí)在env_auto.c中也有定義,說明我們要跳轉(zhuǎn)的文件即為env_atuo.c文件。
在 saveenv函數(shù)中,并沒有看到有關(guān)于mmc寫扇區(qū)的函數(shù),說明我們還需要進(jìn)一步跳轉(zhuǎn)到對應(yīng)的子函數(shù)中去分析。
??4.我們可以再次根據(jù)saveenv命令的打印提示,在最后還會(huì)打印“done”這個(gè)信息,這樣我們就可以更新這個(gè)信息,對當(dāng)前函數(shù)中的三個(gè)子函數(shù)進(jìn)行分析,看下哪一個(gè)子函數(shù)中有這個(gè)字符串的打印。經(jīng)過查看代碼可知最終調(diào)用的函數(shù)即為saveenv_movinand()函數(shù)。
??5.再次跳到movi_write_env()函數(shù)中查看一下寫入到mmc中的地址。
??6.在這個(gè)函數(shù)中即為實(shí)現(xiàn)環(huán)境變量寫入作用,再次跳到movi_write()函數(shù)中查看一下這個(gè)函數(shù)參數(shù)作用。
??可以看到,movi_write()函數(shù)參數(shù)作用分別為:mmc設(shè)備編號(hào)、寫入mmc的起始扇區(qū)、寫入的扇區(qū)個(gè)數(shù)、寫入的環(huán)境變量內(nèi)容。
??我們可以在這個(gè)函數(shù)中加入printf函數(shù)打印一下寫入的扇區(qū)地址和扇區(qū)數(shù)量。然后再重新編譯uboot,燒寫到SD卡中再次啟動(dòng)查看效果。
TINY4412 # save Saving Environment to SMDK bootable device... start=1025,blkcnt=32 done TINY4412 #
-
Linux
+關(guān)注
關(guān)注
87文章
11415瀏覽量
212264 -
Uboot
+關(guān)注
關(guān)注
4文章
126瀏覽量
28733
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
如何添加自定義單板
如何快速創(chuàng)建用戶自定義Board和App工程

Altium Designer 15.0自定義元件設(shè)計(jì)

think-cell:自定義think-cell(四)

智能語音識(shí)別照明解決方案,平臺(tái)自定義,中英切換

think-cell;自定義think-cell(一)

創(chuàng)建自定義的基于閃存的引導(dǎo)加載程序(BSL)

如何創(chuàng)建TestStand自定義步驟

EtherCAT運(yùn)動(dòng)控制器PT/PVT實(shí)現(xiàn)用戶自定義軌跡規(guī)劃

HarmonyOS開發(fā)案例:【 自定義彈窗】

AWTK 開源串口屏開發(fā)(18) - 用 C 語言自定義命令

TSMaster 自定義 LIN 調(diào)度表編程指導(dǎo)

HarmonyOS開發(fā)案例:【UIAbility和自定義組件生命周期】

評(píng)論