🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习
🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发
❄️作者主页:一个平凡而乐于分享的小比特的个人主页
✨收录专栏:Linux,本专栏目的在于,记录学习Linux操作系统的总结
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

DTC、DTS、DTSI、DTBO 关系详解
📌 一、核心关系总览
源码文件(.dts) → 头文件(.dtsi) → 预处理(.dts) → 编译(.dtb) → 重载(.dtbo)
│ │ │ │
└──────┬───────┘ └──────┬───────┘
│ │
人工编写 Device Tree Compiler(DTC)
(预处理 + 编译)
📊 二、详细对比表格
| 组件 | 全称 | 作用 | 文件类型 | 类比解释 |
|---|---|---|---|---|
| DTC | Device Tree Compiler | 设备树编译器,将.dts/.dtsi编译成二进制.dtb | 工具软件 | 编译器 (如gcc) |
| DTS | Device Tree Source | 设备树源码文件,描述硬件配置 | 文本文件(.dts) | C语言源文件 (.c) |
| DTSI | Device Tree Source Include | 设备树头文件,公共硬件描述 | 文本文件(.dtsi) | C语言头文件 (.h) |
| DTB | Device Tree Blob | 二进制设备树,内核直接读取 | 二进制文件(.dtb) | 可执行文件 (.exe/.elf) |
| DTBO | Device Tree Blob Overlay | 设备树叠加层,用于动态修改DTB | 二进制文件(.dtbo) | 补丁文件/插件 |
🎯 三、详细说明与场景示例
1. DTC(Device Tree Compiler)- 编译器
bash
# DTC工作示例
dtc -I dts -O dtb -o my_board.dtb my_board.dts
# ↑将dts编译成dtb ↓将dtb反编译为dts
dtc -I dtb -O dts -o my_board.dts my_board.dtb
2. DTS(设备树源文件)- 主板专属配置
dts
// my_board.dts
/dts-v1/;
#include "soc_base.dtsi" // 包含SoC通用配置
#include "display.dtsi" // 包含显示模块配置
/ {
model = "My Custom Board";
compatible = "mycompany,myboard";
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x40000000>;
};
// 板级特定配置
gpio_keys {
compatible = "gpio-keys";
button1 {
gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
};
};
};
3. DTSI(设备树头文件)- 通用模块定义
dtsi
// soc_base.dtsi - SoC厂商提供
/ {
cpus {
cpu@0 {
compatible = "arm,cortex-a53";
device_type = "cpu";
};
cpu@1 {
compatible = "arm,cortex-a53";
device_type = "cpu";
};
};
soc {
serial0: serial@11000000 {
compatible = "ns16550a";
reg = <0x11000000 0x1000>;
};
gpio0: gpio@10000000 {
compatible = "snps,dw-apb-gpio";
reg = <0x10000000 0x1000>;
};
};
};
4. DTBO(设备树叠加层)- 硬件扩展/修改
dts
// 添加一个新的I2C设备
/dts-v1/;
/plugin/;
&i2c1 { // 引用原设备树中的i2c1节点
status = "okay";
temperature_sensor: lm75@48 {
compatible = "national,lm75";
reg = <0x48>;
};
};
🔄 四、完整编译流程示例
# 文件结构:
# soc_vendor/
# ├── common/
# │ ├── soc_base.dtsi (SoC基础定义)
# │ └── display.dtsi (显示模块定义)
# └── boards/
# ├── board_v1.dts (V1版硬件)
# └── board_v2.dts (V2版硬件)
# 编译流程:
1. 预处理:dtc -E -o board_v1_temp.dts board_v1.dts
↓
board_v1.dts + soc_base.dtsi + display.dtsi → board_v1_temp.dts
2. 编译:dtc -I dts -O dtb -o board_v1.dtb board_v1_temp.dts
↓
board_v1_temp.dts → board_v1.dtb (内核可加载)
3. 制作叠加层:dtc -@ -I dts -O dtb -o add_sensor.dtbo add_sensor.dts
🛠 五、实际应用场景
场景1:同一SoC,不同主板
SoC: Qualcomm Snapdragon 888 (sd888.dtsi)
├── 手机A: phone_a.dts (包含sd888.dtsi,添加手机A特有配置)
└── 平板B: tablet_b.dts (包含sd888.dtsi,添加平板B特有配置)
场景2:硬件扩展板(HAT)
bash
# Raspberry Pi HAT示例
原始DTB: bcm2711-rpi-4b.dtb
HAT DTBO: rpi-display.dtbo
应用叠加: sudo dtoverlay rpi-display.dtbo
结果: 原始DTB + DTBO → 运行时合并的设备树
场景3:内核模块动态配置
c
// 驱动程序通过设备树获取硬件信息
static int my_driver_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
const char *model = of_get_property(np, "model", NULL);
// 从设备树读取配置
}
📈 六、关系可视化
DTSI 头文件
通用硬件描述
DTS 源文件
主板特定配置
DTC 编译器
预处理
展开的DTS
编译
DTB 二进制文件
DTBO 叠加层
运行时合并
最终设备树
内核使用
💡 七、关键要点总结
-
层次化设计:
- DTSI:芯片级通用配置
- DTS:板级特定配置
- DTBO:运行时动态修改
-
编译链 :
.dts + .dtsi → DTC → .dtb -
叠加机制 :
.dtb + .dtbo → 运行时合并设备树 -
主要优势:
- 硬件描述与内核代码分离
- 同一内核支持多种硬件
- 支持动态硬件配置
-
典型路径(Linux内核中):
/arch/arm/boot/dts/ # 存放DTS/DTSI文件 ├── vendor_soc.dtsi ├── board_v1.dts └── overlays/ # DTBO文件
通过这种架构,Linux内核可以保持硬件无关性,而硬件配置信息通过设备树灵活传递,大大提高了嵌入式系统的可移植性和可维护性。