作為嵌入式開發(fā)者,U-Boot是我們調(diào)試、適配板卡的核心工具,而bdinfo命令更是板級(jí)信息調(diào)試的“利器”——它能直觀打印內(nèi)存布局、Flash信息、網(wǎng)絡(luò)配置、時(shí)鐘頻率等核心參數(shù)。但原廠的bdinfo.c往往是“大而全”的通用實(shí)現(xiàn),適配自研板卡時(shí),要么冗余打印拖慢調(diào)試效率,要么缺少我們需要的自定義硬件信息。
今天就結(jié)合bdinfo.c的核心邏輯,手把手教你做功能裁剪、擴(kuò)展、私有定制,讓bdinfo完全貼合自研板卡的調(diào)試需求!

一、先理清:bdinfo.c核心價(jià)值與定制思路
bdinfo.c的核心是實(shí)現(xiàn)bdinfo命令,通過(guò)封裝各類打印函數(shù)(print_num/print_mhz/print_eth等),基于bd_t(板級(jí)信息結(jié)構(gòu)體)和全局gd指針,按不同架構(gòu)(ARM/RISC-V/PPC等)差異化打印硬件參數(shù)。
我們的定制思路圍繞3個(gè)核心需求:
?裁剪:刪掉自研板卡用不到的打印邏輯,減小U-Boot鏡像體積;
?擴(kuò)展:新增自研板卡的自定義硬件信息打?。ㄈ缬布姹?、PMIC狀態(tài));
?定制:修改輸出格式,適配自研調(diào)試工具(如JSON格式、固定分隔符)。
二、實(shí)戰(zhàn)1:功能裁剪——精簡(jiǎn)冗余打印,減小鏡像體積
自研板卡往往是“極簡(jiǎn)設(shè)計(jì)”:比如只有單網(wǎng)口、無(wú)外置Flash、不需要多DRAM Bank打印,這些冗余代碼不僅增加鏡像體積,還會(huì)在調(diào)試時(shí)輸出無(wú)關(guān)信息,干擾判斷。
適用場(chǎng)景
?自研ARM板卡只有eth0,不需要eth1-eth5打??;
?板卡無(wú)Flash芯片,無(wú)需Flash起始地址/大小打印;
?不需要LCD/VIDEO相關(guān)的幀緩沖(FB base)打印。
裁剪步驟(以ARM架構(gòu)為例)
步驟1:精簡(jiǎn)以太網(wǎng)打印
原廠代碼會(huì)遍歷eth0-eth5,但我們只有單網(wǎng)口,直接修改print_eth_ip_addr函數(shù),只保留eth0:
staticinlinevoidprint_eth_ip_addr(void){// 只保留eth0,刪除eth1-eth5的條件編譯print_eth(0);printf("IP addr = %sn",env_get("ipaddr"));}
步驟2:刪除Flash相關(guān)打印
如果板卡無(wú)Flash,直接注釋/刪除print_bi_flash函數(shù)的調(diào)用(以ARM架構(gòu)的do_bdinfo為例):
staticintdo_bdinfo(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[]){bd_t*bd = gd->bd;print_num("arch_number",bd->bi_arch_number);print_bi_boot_params(bd);print_bi_dram(bd);// 【裁剪】刪除Flash打?。ò蹇o(wú)Flash)// print_bi_flash(bd);// ... 原有邏輯保留// ... 其余邏輯不變}
步驟3:關(guān)閉LCD/VIDEO相關(guān)打印
如果板卡無(wú)顯示模塊,刪除幀緩沖打?。?/span>
// 【裁剪】注釋掉FB base打印// print_num("FB base ", gd->fb_base);
裁剪核心原則
?優(yōu)先用條件編譯宏(如CONFIG_MY_BOARD_NO_FLASH)封裝裁剪邏輯,便于后續(xù)開關(guān):
print_bi_flash(bd);
?只刪除“打印調(diào)用”,不刪除底層函數(shù)(如print_bi_flash),避免影響其他架構(gòu)/板卡復(fù)用。
三、實(shí)戰(zhàn)2:功能擴(kuò)展——新增自定義板級(jí)信息打印
這是最常用的定制場(chǎng)景:比如打印自研板卡的硬件版本、PMIC電壓、傳感器ID、自定義保留內(nèi)存區(qū)域等。
適用場(chǎng)景
自研ARM板卡需要打?。?/span>
1.硬件版本號(hào)(存儲(chǔ)在gd全局變量的自定義字段);
2.PMIC(電源管理芯片)的工作電壓;
3.自研的安全分區(qū)內(nèi)存地址。
擴(kuò)展步驟
步驟1:定義自定義輔助打印函數(shù)
在bdinfo.c中新增適配自定義信息的打印函數(shù)(復(fù)用原廠的格式化風(fēng)格,保持一致性):
// 新增:打印硬件版本__maybe_unusedstaticvoidprint_board_version(constchar*name, u32 version){// 格式對(duì)齊原廠:左對(duì)齊12字符,后接版本號(hào)(十進(jìn)制)printf("%-12s= V%02d.%02dn", name, (version>>8)&0xFF, version&0xFF);}// 新增:打印PMIC電壓(單位:mV)__maybe_unusedstaticvoidprint_pmic_voltage(constchar*name, u32 voltage_mv){printf("%-12s= %d mVn", name, voltage_mv);}// 新增:打印自定義保留內(nèi)存__maybe_unusedstaticvoidprint_custom_reserve_mem(constchar*name,ulongstart,ulongsize){print_num(name, start);print_num("-> size", size);}
步驟2:在對(duì)應(yīng)架構(gòu)的do_bdinfo中添加調(diào)用
以ARM架構(gòu)為例,在do_bdinfo函數(shù)中新增自定義打?。ńㄗh放在原有打印邏輯的末尾,便于查看):
staticintdo_bdinfo(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[]){bd_t*bd = gd->bd;// ... 原有打印邏輯(arch_number、DRAM、eth等)保留// 【擴(kuò)展】新增自定義硬件信息打印// 1. 打印硬件版本(假設(shè)gd->arch.board_version是自定義字段)print_board_version("Board Ver", gd->arch.board_version);// 2. 打印PMIC核心電壓(模擬讀取PMIC寄存器)u32 core_volt =read_pmic_reg(PMIC_CORE_VOLT_REG);// 自研PMIC讀取函數(shù)print_pmic_voltage("PMIC Core", core_volt);// 3. 打印安全分區(qū)內(nèi)存print_custom_reserve_mem("Secure Area",0x90000000,0x100000);print_baudrate();// ... 其余原有邏輯保留return0;}
步驟3:用條件編譯封裝擴(kuò)展邏輯
為了便于開關(guān)自定義打印,新增全局宏CONFIG_MY_BOARD_CUSTOM_BDINFO:
// 自定義打印邏輯print_board_version("Board Ver", gd->arch.board_version);print_pmic_voltage("PMIC Core", core_volt);print_custom_reserve_mem("Secure Area",0x90000000,0x100000);
然后在板卡的configs/my_board_defconfig中添加:
CONFIG_MY_BOARD_CUSTOM_BDINFO=y
四、實(shí)戰(zhàn)3:私有定制——適配自研調(diào)試工具
原廠bdinfo輸出是“純文本”,如果需要對(duì)接自研的調(diào)試解析工具(如自動(dòng)解析參數(shù)的腳本),可以定制輸出格式(如JSON、固定分隔符)。
適用場(chǎng)景
讓bdinfo輸出JSON格式,便于上位機(jī)腳本解析內(nèi)存、波特率、自定義硬件版本等信息。
定制步驟
步驟1:修改核心打印函數(shù)為JSON格式
以print_num為例,修改為JSON鍵值對(duì)格式:
__maybe_unusedstaticvoidprint_num(constchar*name, ulong value){// 原廠格式:printf("%-12s= 0x%08lXn", name, value);// 定制為JSON格式(注意逗號(hào)分隔,最后一個(gè)字段無(wú)逗號(hào))printf(" "%s": "0x%08lX",n", name, value);}// 同步修改自定義打印函數(shù)為JSON格式__maybe_unusedstaticvoidprint_board_version(constchar*name, u32 version){printf(" "%s": "V%02d.%02d"n", name, (version>>8)&0xFF, version&0xFF);}
步驟2:包裹整體輸出為JSON結(jié)構(gòu)
在do_bdinfo函數(shù)開頭/結(jié)尾添加JSON首尾標(biāo)識(shí):
staticintdo_bdinfo(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[]){bd_t*bd = gd->bd;// JSON開頭printf("{n");print_num("arch_number",bd->bi_arch_number);print_bi_boot_params(bd);print_bi_dram(bd);// ... 其余打印邏輯(含自定義)print_board_version("Board Ver", gd->arch.board_version);// JSON結(jié)尾printf("}n");return0;}
定制后輸出效果
{"arch_number":"0x00000000","boot_params":"0x80000100","DRAM bank":"0x00000000","-> start":"0x80000000","-> size":"0x10000000","Board Ver":"V01.02"}
五、定制擴(kuò)展的最佳實(shí)踐
1.優(yōu)先用條件編譯,避免硬改:所有定制邏輯都用CONFIG_MY_BOARD_XXX宏封裝,便于不同板卡復(fù)用、開關(guān);
2.復(fù)用原廠函數(shù)風(fēng)格:新增打印函數(shù)時(shí),對(duì)齊原廠的格式化規(guī)則(如%-12s左對(duì)齊),保持輸出可讀性;
3.利用__weak函數(shù)擴(kuò)展:如果需要修改架構(gòu)級(jí)的核心邏輯(如PPC的board_detail),優(yōu)先用__weak重寫,而非直接修改原廠函數(shù):
// 自研板卡重寫board_detailvoidboard_detail(void){print_num("Custom Param",0x12345678);}
4.編譯測(cè)試驗(yàn)證:
?編譯:make my_board_defconfig && make,確保無(wú)編譯錯(cuò)誤;
?燒錄:將新U-Boot燒錄到板卡;
?驗(yàn)證:執(zhí)行bdinfo命令,檢查打印內(nèi)容是否符合預(yù)期。
六、總結(jié)
bdinfo.c是U-Boot板級(jí)調(diào)試的“窗口”,通過(guò)裁剪冗余代碼、擴(kuò)展自定義信息、定制輸出格式,既能減小U-Boot鏡像體積,又能讓調(diào)試信息精準(zhǔn)匹配自研板卡的需求。
核心要點(diǎn)回顧:
1.裁剪:聚焦自研板卡的硬件特性,刪除無(wú)關(guān)打印,用宏控制開關(guān);
2.擴(kuò)展:復(fù)用原廠打印風(fēng)格,新增自定義輔助函數(shù),在對(duì)應(yīng)架構(gòu)的do_bdinfo中調(diào)用;
3.定制:適配調(diào)試工具的輸出格式(如JSON),兼顧可讀性和自動(dòng)化解析。
掌握這些技巧,讓bdinfo從“通用工具”變成貼合你自研板卡的“專屬調(diào)試助手”!
-
嵌入式
+關(guān)注
關(guān)注
5210文章
20679瀏覽量
337347 -
u-boot
+關(guān)注
關(guān)注
0文章
140瀏覽量
39964 -
命令
+關(guān)注
關(guān)注
5文章
759瀏覽量
23978
發(fā)布評(píng)論請(qǐng)先 登錄
嵌入式系統(tǒng)中U-Boot 基本特點(diǎn)及其移植方法
嵌入式系統(tǒng)中U-Boot 基本特點(diǎn)及其移植方法
U-Boot的啟動(dòng)及移植分析
嵌入式U-BOOT的啟動(dòng)流程及移植
基于u-boot的嵌入式系統(tǒng)實(shí)驗(yàn)板BSP研究
U-Boot在基于BF561的嵌入式Linux系統(tǒng)上的移植
u-boot學(xué)習(xí)指南
嵌入式Linux開發(fā)實(shí)用教程(試用)
嵌入式Linux系統(tǒng)移植開發(fā)-(1)基于Yocto構(gòu)建嵌入式u-boot,內(nèi)核,文件系統(tǒng)
U-Boot架構(gòu)淺析
創(chuàng)建自定義的u-boot命令
tiny4412編譯與移植U-Boot
嵌入式系統(tǒng)中u-boot和bootloader詳解
Linux U-Boot開發(fā)指南
深度剖析U-Boot ADC Uclass:從架構(gòu)到實(shí)戰(zhàn)的全維度解析
玩轉(zhuǎn)U-Boot bdinfo:嵌入式bsp開發(fā)者的定制、擴(kuò)展與裁剪實(shí)戰(zhàn)指南
評(píng)論