一、核心概念先厘清
首先明确两个基础概念:
- 配置文件:是编译期/启动初期的静态配置,以代码/脚本形式存在,决定引导程序自身的编译选项、初始化逻辑和启动行为;
- 设备树(Device Tree, DTS/DTB) :是硬件描述的标准化数据结构,以二进制(DTB)形式传递,核心是描述硬件拓扑和参数,解耦软件与硬件。
二、U-Boot 中的配置文件 vs 设备树
1. U-Boot 配置文件
功能
U-Boot 的配置文件分为两类,核心作用是定义 U-Boot 自身的编译和运行规则:
- 编译期配置(
.config/Kconfig/defconfig) :- 决定编译哪些功能模块(如是否支持 USB、网络、SPI Flash);
- 定义硬件基础参数(如 CPU 主频、内存地址/大小、串口波特率);
- 指定默认启动参数、环境变量初始值;
- 配置板级专属逻辑(如引脚复用、时钟初始化的硬编码参数)。
- 运行期配置(环境变量脚本,如
bootcmd/bootargs) :- 定义启动流程(如从哪个存储介质加载内核、内核镜像路径);
- 传递给内核的启动参数(如根文件系统路径、控制台串口);
- 自定义命令(如批量烧写固件、硬件自检脚本)。
解析/使用时机
- 编译期配置:在 U-Boot 编译阶段 由 Make 工具解析,直接编译进 U-Boot 镜像(
u-boot.bin),决定镜像的功能和基础行为; - 运行期配置:
- 出厂默认值:编译进镜像,U-Boot 启动初期(初始化阶段) 加载到环境变量区域;
- 自定义值:若存储在 Flash/NVRAM 中,U-Boot 初始化后期(环境变量初始化阶段) 从存储介质读取并覆盖默认值;
bootcmd等核心变量:U-Boot 启动最后阶段(自动引导阶段) 执行,触发内核加载流程。
2. U-Boot 设备树(DTB)
功能
- 标准化描述硬件:CPU、内存、外设(串口/网口/SPI/I2C)的地址、中断号、时钟、引脚配置等;
- 传递硬件信息给内核:U-Boot 不直接使用设备树的大部分内容,仅做少量解析(如获取内存大小),核心是将 DTB 加载到内存并传递给 Linux 内核;
- 简化 U-Boot 移植:硬件参数不再硬编码到 U-Boot 代码,而是通过设备树统一管理。
解析/使用时机
- U-Boot 启动中期(板级初始化阶段) :解析设备树的基础信息(如内存节点
memory、串口节点serial),用于自身的硬件初始化(如设置内存控制器、初始化串口); - U-Boot 引导内核前:将 DTB 镜像加载到内存指定地址,与内核镜像一起传递给内核;
- 内核启动后:内核解析 DTB,完成所有硬件的初始化(U-Boot 不再使用 DTB)。
三、PMON 中的配置文件 vs 设备树
PMON(OpenBIOS)是多用于 MIPS 架构的引导程序,设计理念与 U-Boot 差异较大,设备树的使用也更浅:
1. PMON 配置文件
功能
PMON 的配置以源码级配置(config.h/board/*/config.c)和脚本(pmonrc)为主:
- 编译期配置:定义 CPU 类型、内存布局、外设驱动的编译开关、默认控制台;
- 运行期脚本(
pmonrc):类似 U-Boot 的环境变量,定义启动命令(如load/boot命令)、内核参数、硬件自检逻辑; - 板级参数配置:硬编码硬件参数(如串口波特率、Flash 分区),这一点比 U-Boot 更依赖静态配置。
解析/使用时机
- 编译期配置:PMON 编译阶段 解析,直接编译进
pmon.bin; - 运行期脚本:
- 内置默认脚本:PMON 启动初期(初始化完成后) 执行;
- 外置
pmonrc:若存储在 Flash/硬盘中,PMON 启动后 自动加载并执行; - 启动命令:用户输入
boot或自动引导阶段 执行,加载并启动内核。
2. PMON 中的设备树
功能
PMON 对设备树的支持远弱于 U-Boot,核心功能仅为:
- 部分版本支持读取 DTB 文件,提取少量硬件参数(如内存大小);
- 传递 DTB 给内核(仅部分适配的 PMON 版本支持);
- 大部分场景下,PMON 不依赖设备树,硬件信息仍以硬编码配置为主。
解析/使用时机
- 仅在 引导内核前 被动加载 DTB 到内存,几乎不解析 DTB 内容;
- 内核启动后由内核自行解析 DTB,PMON 全程不主动使用设备树的硬件描述。
四、核心差异对比表
| 维度 | U-Boot | PMON |
|---|---|---|
| 配置文件核心 | 编译期 .config + 运行期环境变量 |
编译期硬编码 + 运行期 pmonrc 脚本 |
| 设备树依赖度 | 高(核心硬件描述依赖 DTB) | 低(仅传递 DTB,自身几乎不解析) |
| 配置解析时机 | 编译期 + 启动初期/引导前 | 编译期 + 启动后 |
| 设备树解析时机 | 板级初始化 + 引导内核前 | 仅引导内核前加载(几乎不解析) |
总结
- 配置文件 :核心是定义引导程序自身的行为 (编译选项、启动流程、基础硬件参数),U-Boot/PMON 均在编译期解析静态配置 ,启动初期/后期解析运行期脚本;
- 设备树 :核心是标准化描述硬件并传递给内核,U-Boot 在启动中期解析基础硬件信息用于自身初始化,引导内核前传递给内核;PMON 几乎不解析设备树,仅被动传递给内核;
- 核心区别:配置文件是引导程序"管自己"的规则,设备树是引导程序"给内核传递硬件信息"的载体,U-Boot 对设备树的依赖和解析程度远高于 PMON。