0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

玩转U-Boot bdinfo:嵌入式bsp开发者的定制、扩展与裁剪实战指南

jf_44130326 来源:Linux1024 2026-02-24 15:26 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

作为嵌入式开发者,U-Boot是我们调试、适配板卡的核心工具,而bdinfo命令更是板级信息调试的利器”——它能直观打印内存布局、Flash信息、网络配置、时钟频率等核心参数。但原厂的bdinfo.c往往是大而全的通用实现,适配自研板卡时,要么冗余打印拖慢调试效率,要么缺少我们需要的自定义硬件信息。

今天就结合bdinfo.c的核心逻辑,手把手教你做功能裁剪、扩展、私有定制,让bdinfo完全贴合自研板卡的调试需求!

wKgZO2mRDtmAPNCKAAARj2YXOY8495.png

一、先理清:bdinfo.c核心价值与定制思路

bdinfo.c的核心是实现bdinfo命令,通过封装各类打印函数(print_num/print_mhz/print_eth等),基于bd_t(板级信息结构体)和全局gd指针,按不同架构(ARM/RISC-V/PPC等)差异化打印硬件参数。

我们的定制思路围绕3个核心需求:

裁剪:删掉自研板卡用不到的打印逻辑,减小U-Boot镜像体积;

扩展:新增自研板卡的自定义硬件信息打印(如硬件版本、PMIC状态);

定制:修改输出格式,适配自研调试工具(如JSON格式、固定分隔符)。

二、实战1:功能裁剪——精简冗余打印,减小镜像体积

自研板卡往往是极简设计:比如只有单网口、无外置Flash、不需要多DRAM Bank打印,这些冗余代码不仅增加镜像体积,还会在调试时输出无关信息,干扰判断。

适用场景

自研ARM板卡只有eth0,不需要eth1-eth5打印;

板卡无Flash芯片,无需Flash起始地址/大小打印;

不需要LCD/VIDEO相关的帧缓冲(FB base)打印。

裁剪步骤(以ARM架构为例)

步骤1:精简以太网打印

原厂代码会遍历eth0-eth5,但我们只有单网口,直接修改print_eth_ip_addr函数,只保留eth0

staticinlinevoidprint_eth_ip_addr(void){#ifdefined(CONFIG_CMD_NET) // 只保留eth0,删除eth1-eth5的条件编译print_eth(0);printf("IP addr   = %sn",env_get("ipaddr"));#endif}

步骤2:删除Flash相关打印

如果板卡无Flash,直接注释/删除print_bi_flash函数的调用(以ARM架构的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打印(板卡无Flash) // print_bi_flash(bd);#ifdefCONFIG_SYS_MEM_RESERVE_SECURE // ... 原有逻辑保留#endif // ... 其余逻辑不变}

步骤3:关闭LCD/VIDEO相关打印

如果板卡无显示模块,删除帧缓冲打印:

#ifdefined(CONFIG_LCD) || defined(CONFIG_VIDEO) // 【裁剪】注释掉FB base打印// print_num("FB base ", gd->fb_base);#endif

裁剪核心原则

优先用条件编译宏(如CONFIG_MY_BOARD_NO_FLASH)封装裁剪逻辑,便于后续开关:

#ifndefCONFIG_MY_BOARD_NO_FLASHprint_bi_flash(bd);#endif

只删除打印调用,不删除底层函数(如print_bi_flash),避免影响其他架构/板卡复用。

三、实战2:功能扩展——新增自定义板级信息打印

这是最常用的定制场景:比如打印自研板卡的硬件版本、PMIC电压、传感器ID、自定义保留内存区域等。

适用场景

自研ARM板卡需要打印:

1.硬件版本号(存储在gd全局变量的自定义字段);

2.PMIC电源管理芯片)的工作电压;

3.自研的安全分区内存地址。

扩展步骤

步骤1:定义自定义辅助打印函数

bdinfo.c中新增适配自定义信息的打印函数(复用原厂的格式化风格,保持一致性):

// 新增:打印硬件版本__maybe_unusedstaticvoidprint_board_version(constchar*name, u32 version){ // 格式对齐原厂:左对齐12字符,后接版本号(十进制)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);}// 新增:打印自定义保留内存__maybe_unusedstaticvoidprint_custom_reserve_mem(constchar*name,ulongstart,ulongsize){print_num(name, start);print_num("-> size", size);}

步骤2:在对应架构的do_bdinfo中添加调用

ARM架构为例,在do_bdinfo函数中新增自定义打印(建议放在原有打印逻辑的末尾,便于查看):

staticintdo_bdinfo(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[]){bd_t*bd = gd->bd;// ... 原有打印逻辑(arch_number、DRAM、eth等)保留 // 【扩展】新增自定义硬件信息打印 // 1. 打印硬件版本(假设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读取函数 print_pmic_voltage("PMIC Core", core_volt); // 3. 打印安全分区内存 print_custom_reserve_mem("Secure Area",0x90000000,0x100000);print_baudrate();// ... 其余原有逻辑保留return0;}

步骤3:用条件编译封装扩展逻辑

为了便于开关自定义打印,新增全局宏CONFIG_MY_BOARD_CUSTOM_BDINFO

#ifdefCONFIG_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);#endif

然后在板卡的configs/my_board_defconfig中添加:

CONFIG_MY_BOARD_CUSTOM_BDINFO=y

四、实战3:私有定制——适配自研调试工具

原厂bdinfo输出是纯文本,如果需要对接自研的调试解析工具(如自动解析参数的脚本),可以定制输出格式(如JSON、固定分隔符)。

适用场景

bdinfo输出JSON格式,便于上位机脚本解析内存、波特率、自定义硬件版本等信息。

定制步骤

步骤1:修改核心打印函数为JSON格式

print_num为例,修改为JSON键值对格式:

__maybe_unusedstaticvoidprint_num(constchar*name, ulong value){ // 原厂格式:printf("%-12s= 0x%08lXn", name, value); // 定制为JSON格式(注意逗号分隔,最后一个字段无逗号)printf(" "%s": "0x%08lX",n", name, value);}// 同步修改自定义打印函数为JSON格式__maybe_unusedstaticvoidprint_board_version(constchar*name, u32 version){printf(" "%s": "V%02d.%02d"n", name, (version>>8)&0xFF, version&0xFF);}

步骤2:包裹整体输出为JSON结构

do_bdinfo函数开头/结尾添加JSON首尾标识:

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结尾 printf("}n");return0;}

定制后输出效果

{"arch_number":"0x00000000","boot_params":"0x80000100","DRAM bank":"0x00000000","-> start":"0x80000000","-> size":"0x10000000","Board Ver":"V01.02"}

五、定制扩展的最佳实践

1.优先用条件编译,避免硬改:所有定制逻辑都用CONFIG_MY_BOARD_XXX宏封装,便于不同板卡复用、开关;

2.复用原厂函数风格:新增打印函数时,对齐原厂的格式化规则(如%-12s左对齐),保持输出可读性;

3.利用__weak函数扩展:如果需要修改架构级的核心逻辑(如PPCboard_detail),优先用__weak重写,而非直接修改原厂函数:

// 自研板卡重写board_detailvoidboard_detail(void){ print_num("Custom Param",0x12345678);}

4.编译测试验证

编译:make my_board_defconfig && make,确保无编译错误;

烧录:将新U-Boot烧录到板卡;

验证:执行bdinfo命令,检查打印内容是否符合预期。

六、总结

bdinfo.cU-Boot板级调试的窗口,通过裁剪冗余代码、扩展自定义信息、定制输出格式,既能减小U-Boot镜像体积,又能让调试信息精准匹配自研板卡的需求。

核心要点回顾:

1.裁剪:聚焦自研板卡的硬件特性,删除无关打印,用宏控制开关;

2.扩展:复用原厂打印风格,新增自定义辅助函数,在对应架构的do_bdinfo中调用;

3.定制:适配调试工具的输出格式(如JSON),兼顾可读性和自动化解析。

掌握这些技巧,让bdinfo通用工具变成贴合你自研板卡的专属调试助手

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5209

    文章

    20625

    浏览量

    336764
  • u-boot
    +关注

    关注

    0

    文章

    135

    浏览量

    39920
  • 命令
    +关注

    关注

    5

    文章

    758

    浏览量

    23914
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    嵌入式系统中U-Boot 基本特点及其移植方法

    在介绍U-Boot 基本特点的基础上,结合U-Boot 移植经历,以MPC8xx 和嵌入式Linux 为背景,分析、探讨U-Boot 的移植方法、过程与相关移植要点, 并给出一些具体配
    发表于 04-15 09:25 17次下载

    嵌入式系统中U-Boot 基本特点及其移植方法

    在介绍U-Boot 基本特点的基础上,结合U-Boot 移植经历,以MPC8xx 和嵌入式Linux 为背景,分析、探讨U-Boot 的移植方法、过程与相关移植要点, 并给出一些具体配
    发表于 05-16 14:52 12次下载

    U-Boot的启动及移植分析

    bootloader 开发嵌入式系统必不可少而且十分重要的部分,U-Boot 为功能强大的bootloader 开发软件。本文详细分析了U-Boo
    发表于 09-01 16:34 27次下载

    嵌入式U-BOOT的启动流程及移植

    摘要:嵌入式系统一般没有通用的bootloader,u-boot是功能强大的bootloader开发软件,但相对也比较复杂。文中对u-boot的启动流程作了介绍,详细给出了
    发表于 02-25 16:00 59次下载

    基于u-boot嵌入式系统实验板BSP研究

    在介绍BSP概念和功能的基础上,讨论了u-boot的移植过程和关键环节。系统启动试验表明移植后的U-BOOT实现了BSP的功能
    发表于 05-26 15:47 33次下载
    基于<b class='flag-5'>u-boot</b>的<b class='flag-5'>嵌入式</b>系统实验板<b class='flag-5'>BSP</b>研究

    U-Boot在基于BF561的嵌入式Linux系统上的移植

    嵌入式开发人员应该在了解U-Boot的工作机理、移植条件后,根据目标板和具体情况灵活裁减U -Boot以提高操作系统移植的稳定性,缩短移植周期,降低产品成本,为后续
    发表于 06-28 11:22 1612次阅读
    <b class='flag-5'>U-Boot</b>在基于BF561的<b class='flag-5'>嵌入式</b>Linux系统上的移植

    u-boot学习指南

    u-boot 是免费的,我们做嵌入式的一般只需要使用 u-boot 即可,但如果你想成为一个比较强的嵌入式系统工程师,而且还做了自己开发板,
    发表于 11-17 15:54 2次下载

    嵌入式Linux开发实用教程(试用)

    高超的技术使得 U-Boot 能够非常容易地被移植 到多种嵌入式 CPU 中, 支持多种嵌入式操作系统内核的引导。不少 U-Boot 源码就是 linux。
    发表于 04-28 16:30 2次下载

    如何在U-Boot中实现对Yaffs镜像的设计?

    U-Boot是目前广泛使用的嵌入式操作系统通用引导程序,具有功能丰富强大,支持多种操作系统和CPU体系,易于功能扩展和移植,源码开放等多种优点。U-Boot,全称 Universal
    的头像 发表于 08-29 05:02 4469次阅读
    如何在<b class='flag-5'>U-Boot</b>中实现对Yaffs镜像的设计?

    嵌入式Linux系统移植开发-(1)基于Yocto构建嵌入式u-boot,内核,文件系统

    基于Yocto构建嵌入式u-boot,内核,文件系统Yocto是什么?简单地概括,它是一个工具,可以用来构建u-boot,kernel,文件系统,交叉编译工具链,等等。Yocto提供了一套完整的全面
    发表于 11-01 17:38 14次下载
    <b class='flag-5'>嵌入式</b>Linux系统移植<b class='flag-5'>开发</b>-(1)基于Yocto构建<b class='flag-5'>嵌入式</b><b class='flag-5'>u-boot</b>,内核,文件系统

    U-Boot架构浅析

    导读:嵌入式Linux系统搭建,bootloader是必不可少的一环,而U-Boot已成嵌入式Linux事实标准。所以较为深入的分析U-Boot的设计,对于更...
    发表于 02-07 11:56 7次下载
    <b class='flag-5'>U-Boot</b>架构浅析

    创建自定义的u-boot命令

    为什么会有这篇文章,因为小生被u-boot源码的设计所吸引了(源码对命令的处理过程)。自定义u-boot命令属于u-boot源码的开发技术啦,可能u
    的头像 发表于 08-08 14:46 1837次阅读

    tiny4412编译与移植U-Boot

    U-Boot 是一个主要用于嵌入式系统的引导加载程序, U-Boot本质是一个裸机程序,是一种普遍用于嵌入式系统中的开源的Bootloader,作用是用来引导操作系统,以及给
    的头像 发表于 08-31 08:59 3396次阅读
    tiny4412编译与移植<b class='flag-5'>U-Boot</b>

    嵌入式系统中u-boot和bootloader详解

    嵌入式软件工程师听说过 u-boot 和 bootloader,但很多工程师依然不知道他们到底是啥。
    发表于 10-20 13:12 2670次阅读

    Linux U-Boot开发指南

    介绍 U-Boot 的编译打包、基本配置、常用命令的使用、基本调试方法等, 为 U-BOOT 的移植及应用开发提供了基础。
    的头像 发表于 03-06 10:28 2612次阅读
    Linux <b class='flag-5'>U-Boot</b><b class='flag-5'>开发指南</b>