📺 B站视频讲解(Bilibili):https://www.bilibili.com/video/BV1k1C9BYEAB/
📘 《Yocto项目实战教程》京东购买链接:Yocto项目实战教程
Bootloader 与 BCT 深度解析:架构、特点、差异与实战示例
本文系统讲解 Jetson 平台 Bootloader 的核心机制与 BCT(Boot Configuration Table)体系,包括其由何而来、为何存在、与行业其他平台的差异、实际开发中如何修改,以及使用示例。全文结构客观、逻辑清晰,适合书籍章节输出(约 4000 字)。

一、Bootloader 的角色与边缘 AI SoC 的启动需求
在几乎所有嵌入式系统中,Bootloader 承担着系统从上电到操作系统运行之间的关键任务。然而,不同 SoC 的启动难度差异巨大。例如:
- NXP i.MX 平台的 Bootloader 主要负责 DDR 初始化与启动 U-Boot;
- Rockchip 平台由闭源 DDR Bin 完成内存初始化,再启动 U-Boot;
- Allwinner、Amlogic 平台结构较简单,多由单阶段或双阶段 Bootloader 完成基本工作;
- NVIDIA Jetson 的启动体系最为复杂,由 BootROM → MB1 → MB2 → UEFI(或 CBoot)组成完整固件链,并需要在 Linux Kernel 启动前完成大量“深度硬件初始化”。
Jetson 的启动难度远超普通 SoC,原因在于其硬件结构中包含:
- 多个协处理器(BPMP、RCE、SCE、DCE 等)
- 多媒体硬件(ISP、NVCSI、NVENC/NVDEC)
- 高速接口(PCIe/SATA/USB3)
- 复杂的 UPHY Lane 复用
- 大规模 GPU 初始化要求
- PMIC 与电源轨严格时序
因此 Jetson 平台必须在 Kernel 启动前,通过 Bootloader 完成一次完整的“硬件自检与初始化”,并确保 GPU、ISP 等硬件在用户态立即可用。
为了管理如此庞大的启动配置,Jetson 引入了其他平台完全没有的 BCT(Boot Configuration Table)体系。
二、什么是 BCT?为什么它不是设备树?
1. 准确定义
BCT(Boot Configuration Table)是 Jetson 启动链中 BootROM、MB1、MB2 使用的一组二进制配置表,用于描述启动所需的所有硬件参数。其本质是一种“结构化二进制数据”,并非文本文件,也不是 Linux 设备树(Device Tree)。
2. BCT = Bootloader 的“硬件初始化说明书”
它包含:
- 电源与 PMIC 的电压配置
- DDR 初始化参数(SDRAM 配置)
- UPHY Lane 复用(PCIe/USB/SATA)
- 存储设备参数(QSPI/UFS/SDMMC)
- 引脚复用(Pinmux/GPIO)
- Carveout(BPMP/DCE/ISP 等固件空间)
- BootROM 安全相关字段(UFUSE、Ratchet 等)
这些参数在 BootROM/MB1 解析后,决定 Jetson 是否能成功启动。
3. 为什么它不像其他平台的设备树?
| 对比项 | Linux Device Tree (DTB) | BCT (Boot Configuration Table) |
|---|---|---|
| 使用者 | Linux Kernel | BootROM / MB1 / MB2 |
| 内容 | 设备拓扑与驱动结构 | 启动所需硬件初始化参数 |
| 修改方式 | DTS 文本 → dtb | DTS 文本 → dtb → BCT bin |
| 作用阶段 | Kernel 运行时 | 上电到 Kernel 之前 |
| 是否可以热更新 | 不可 | 不可,必须刷入 QSPI/Bootloader 镜像 |
因此:
BCT ≠ Device Tree。
它只是使用了 DTS 格式作为“源文件”,最终生成的是 Bootloader 固件使用的二进制表。
4. 为什么 T23x(AGX Orin)开始引入 DTS 格式?
官方给出的理由:
- DTS 为树形结构,表达能力强
- 支持 include/override
- 开发者更容易阅读
- 可复用 Linux 设备树工具链(dtc)
但这并不改变 BCT 的本质:
Bootloader 解析的是二进制 BCT,而不是 DTS/DTB。
三、Jetson 中的四类 BCT 结构(核心内容)
Jetson 启动链中包含多个阶段,不同阶段解析不同的 BCT 文件。
1. BR-BCT(BootROM-BCT)
BootROM 在冷启动时从 QSPI/闪存读取 BR-BCT,它定义:
- 启动设备类型(UFS / QSPI / SDMMC)
- 存储访问参数
- BootROM 安全配置(Ratchet/KDK/SBK 等)
常见启动失败症状:黑屏、不进入 RCM、没有串口输出。
2. MB1-BCT(最复杂、开发者最常修改)
由 MB1 解析,包含:
- Pinmux 与 GPIO 配置
- PMIC Rail 与电源时序
- UPHY Lane 配置(PCIe/USB/SATA 复用)
- 存储设备参数(SD/UFS)
- BootROM Reset PMIC 操作
- 通用控制器产品配置(Prod Config)
MB1-BCT 是最容易影响自定义载板能否启动的关键。
3. Mem-BCT(DDR/EMC 参数)
包含:
- EMC / MC(内存控制器)
- DDR Timing(Training 参数)
- DRAM-ECC 配置
- carveout 空间(BPMP/RCE/ISP 固件)
常见症状:
没有串口输出 → DDR 初始化失败 → Mem-BCT 参数错误。
4. MB2-BCT
由 MB2 使用,内容包括:
- GPIO interrupt mapping
- 安全配置
- 固件加载次序(bpmpfw/dcefw/rcefw)
- 额外的 boot 参数
错误可能导致:摄像头双核固件加载失败,ISP 不工作等。
四、实战示例:修改 Pinmux 并生成新的 BCT
以下示例演示如何在自定义 Carrier Board 上修改某个 GPIO 为输出模式,并正确生成新 BCT。
1. 编辑 MB1-BCT DTS 配置
示例文件:tegra234-mb1-pinmux.dtsi
pinmux@2430000 {
gpio_pz0_ps4 {
nvidia,pins = "gpio_pz0";
nvidia,function = "gpio";
nvidia,pull = <0>;
nvidia,enable-input = <0>; // 输出
nvidia,io-high-voltage = <1>;
};
};
2. 编译 DTS → DTB
dtc -I dts -O dtb -o mb1-pinmux.dtb mb1-pinmux.dtsi
3. 使用 NVIDIA 工具生成 BCT(二进制)
tegrabct_v2 --chip 0x23 --bct mb1-pinmux.dtb --bct_out mb1-pinmux.bct
4. 将 BCT 包含到 Bootloader 镜像中
flash.sh -r -k MB1_BCT mb1-pinmux.bct
完成后,设备将使用新 pinmux 配置启动。
五、与其他 SoC 的本质区别(行业对比)
下面用最直观的表格总结 Jetson 与其他平台在 Bootloader 配置方式上的差异:
| 功能项 | Jetson(Tegra) | NXP i.MX8 | Rockchip | Allwinner | Amlogic |
|---|---|---|---|---|---|
| BootROM 是否读取硬件配置表? | ✔(BR-BCT) | ✘ | ✘ | ✘ | ✘ |
| 是否需要在 Bootloader 完成 GPU/ISP 初始化? | ✔ | ✘ | ✘ | ✘ | ✘ |
| DDR 初始化方式 | Mem-BCT | SPL | DDR Bin | Boot0 | BL2 |
| UPHY lane 配置 | MB1-BCT | DTS(Kernel) | DTS | 少量 | DTS |
| 是否支持多固件协处理器? | ✔(BPMP/RCE/DCE) | 部分 | ✘ | ✘ | ✘ |
| Boot 配置文件格式 | DTS → DTB → BCT | CFG/TXT | DTS | DTS | DTS |
| 是否有强 OTA(A/B + Capsule) | ✔ | ✘ | ✘ | ✘ | ✘ |
结论非常明显:
BCT 是 Jetson 启动链特有的固件机制,其他平台均未采用类似结构。
六、为什么 BCT 不能替代设备树(DTB)?
因为两者用于完全不同的目的。
1. BCT 做的是“硬件初始化”
包括:
- DDR 时序训练
- 电源 Rail 设置
- UPHY lane 配置
- 多媒体 ISP/GPU 提前初始化
2. 设备树(Device Tree)做的是“驱动注册与资源描述”
包括:
- I2C/SPI/UART 节点
- 摄像头端点(endpoint)拓扑
- PCIe/USB 控制器属性
- GPIO 编号与触发方式
一句话:
BCT 决定能否点亮板子;DTB 决定内核如何驱动板子。
七、Bootloader BCT 的调试技巧(实战经验总结)
技巧 1:启动卡死,没有串口输出 → 极有可能是 Mem-BCT 错误
- DDR 参数不正确
- Carveout 设置过大
- ECC 设置错误
技巧 2:上电即关机 → PMIC Rail 的 MB1-BCT 错误
- Rail 配置不匹配实际硬件
- 电压过高/过低被 PMIC 保护
- Power-good 信号没有按时序到达
技巧 3:USB/PCIe 无法工作 → UPHY Lane 错误
Tegra 的 UPHY 复用十分复杂,USB3/PCIe 共享同一 PHY,Lane 配置错误会导致控制器完全无法枚举。
技巧 4:使用 flash.sh 调试单一 BCT 文件
flash.sh -r -k MB1_BCT custom-mb1-bct.bct
允许快速测试 BCT 修改,无需完整刷机。
八、Bootloader 与 BCT 的整体流程图(完整理解)
上电
│
▼
BootROM
│读取 BR-BCT(二进制)
▼
MB1
│读取 MB1-BCT
│初始化:PMIC / Pinmux / UPHY / 时钟 / DDR
▼
Mem-BCT(DDR Training)
│
▼
MB2
│读取 MB2-BCT
│加载固件(bpmpfw/rcefw/dcefw)
▼
UEFI / CBoot
│合并设备树 Overlay
│加载 Kernel
▼
Linux Kernel
│解析 DTB
▼
用户空间
此图清晰地展示:
Bootloader 阶段大量依赖 BCT;Kernel 阶段依赖的是 Device Tree(DTB)。
九、总结:为什么学习 BCT 是开发 Jetson BSP 的关键?
因为:
- BCT 决定了 Jetson 能不能启动
- 是自定义载板最核心的差异适配点
- 是 PMIC/DDR/UPHY 这些关键硬件的初始化入口
- 是所有驱动与应用正常工作的前提
一句话总结:
BCT 是 Jetson Bootloader 的基础,是理解自定义硬件、适配载板、解决启动问题的必修内容。
对于任何基于 Jetson 的产品化开发,理解 BCT = 理解整个启动链路。
十、BCT 实战强化:以自定义载板为例的完整操作流程
下面通过真实代码、二进制编译过程、刷写验证方法,展示 BCT 在工程中的真实作用与修改方式。本小节以“修改 UPHY Lane 以支持自定义板 PCIe + USB3 分配”为例,属于实际开发中最常见、最容易出错的场景之一。
1. 实战背景:为什么要修改 UPHY Lane?
Jetson Orin(T234)平台的 UPHY(高速 SerDes)支持多路复用:
- 同一组 Lane 可以作为 PCIe、USB3、SATA、DP 等不同控制器的物理层。
- 官方开发套件和自定义载板通常不同,需要重新分配。
错误 UPHY 配置 = PCIe 不能枚举 / USB3 无法工作 / SATA 不识别。
例:你设计的板子把 UPHY Lane 0 给了 USB3,而不是官方的 PCIe。
那么你必须修改 BCT(而不是 Kernel DTS)。
2. 修改 BCT 配置文件(DTS 源文件)
示例文件:tegra234-mb1-uphy-lane.dtsi
uphy-lane@0 {
nvidia,lane-number = <0>;
nvidia,usage = "usb3"; // 将原本的 PCIe 改成 USB3
nvidia,controller = <&xusb_padctl>;
nvidia,usb-mode = <1>; // 1 = USB3 SuperSpeed
};
uphy-lane@1 {
nvidia,lane-number = <1>;
nvidia,usage = "pcie"; // 保留 PCIe 用途
nvidia,controller = <&pcie_c5>;
};
说明:
usage字段是真正决定 Lane 分配的关键字段。- 错误配置会导致 UART、USB、PCIe 都无任何输出。
3. 编译 DTS → DTB(树状结构)
dtc -I dts -O dtb -o mb1-uphy-temp.dtb tegra234-mb1-uphy-lane.dtsi
验证 dtb 内容是否正确:
dtdump mb1-uphy-temp.dtb | grep uphy
4. 生成 BCT(二进制配置表)
使用 NVIDIA 工具:tegrabct_v2
tegrabct_v2 \
--chip 0x23 \
--bct mb1-uphy-temp.dtb \
--bct_out mb1-uphy-lane.bct
输出文件即为 BootROM/MB1 可解析的真正 BCT 二进制表。
5. 将修改后的 BCT 烧录到板子
无需完整刷机,直接更新 MB1-BCT:
sudo ./flash.sh -r -k MB1_BCT mb1-uphy-lane.bct jetson-orin-nano-devkit mmcblk0p1
解释:
-r不重新刷 RootFS-k MB1_BCT只更新 MB1 BCT 分区- 对开发效率极大提升
6. 重启并观察 Boot Log(串口)
在 UART 上,应看到:
[MB1]: UPHY lane 0 → USB3 mode
[MB1]: UPHY lane 1 → PCIe mode
[XUSB]: Pad configuration OK
[PCIe]: link up on C5
如果看到:
[PCIe]: link timeout
说明 lane 没配置对。
7. 在 Linux 中验证效果
检查 USB3 是否上线
dmesg | grep -i xhci
lsusb -t
检查 PCIe 枚举是否正常
lspci -vv
8. 实战技巧总结(非常重要)
技巧 1:UPHY 配置时必须同时确认 PMIC Rail 状态
某些 USB3 端口需要额外的 5V enable signal,若 PMIC 没配置,USB3 仍然无法工作。
技巧 2:不要把 Kernel DTS 当作 UPHY 配置入口
UPHY 属于 Bootloader 初始化阶段,Kernel DTS 修改无效。
技巧 3:建议每次只改一个 BCT 文件并单独刷新
避免多个变量同时变化,难以定位问题。
技巧 4:使用 diff 找到修改内容
diff -u origin-uphy.dtsi your-uphy.dtsi
十一、全文总结:BCT 的本质与实战价值
结合代码实战,我们可以更清晰理解:
- BCT 是 Bootloader 用来初始化硬件的二进制表;
- DTS 仅是生成 BCT 的“配置语言”,不是设备树;
- BCT 修改的典型场景包括 DDR、PMIC、UPHY、Pinmux;
- Kernel DTS 与 BCT 完全不同,作用阶段不同;
- 自定义载板开发中必须掌握 BCT,才能保证设备可正常上电启动;
- Jetson 是行业中唯一采用“BCT 多配置表机制”的 ARM SoC;
- 理解并掌握 BCT,是 Jetson BSP 工程师的核心能力之一。
📺 B站视频讲解(Bilibili):https://www.bilibili.com/video/BV1k1C9BYEAB/
📘 《Yocto项目实战教程》京东购买链接:Yocto项目实战教程
4202

被折叠的 条评论
为什么被折叠?



