1. 设备树基础概念

1.1 什么是设备树(Device Tree)

设备树(Device Tree,DT)是一种描述硬件资源的数据结构,它使用树形节点来表述系统中所有可寻址的设备及其连接关系。设备树源文件(.dts)经过设备树编译器(dtc)编译生成二进制设备树(.dtb),在系统启动时由引导加载程序传递给内核。

设备树的核心思想是:将硬件描述从内核代码中剥离出来,使同一份内核二进制能够适配多种硬件平台,而无需重新编译。

关键术语速查表
术语全称说明
DTSDevice Tree Source设备树源文件,人类可读的文本格式
DTBDevice Tree Blob编译后的二进制设备树,内核直接使用
DTCDevice Tree Compiler将 DTS 编译为 DTB 的工具
DTBODevice Tree Blob Overlay设备树叠加层,用于运行时修改
OFOpen Firmware设备树的起源规范,现由 ePAPR 标准继承
💡 记忆点:设备树本质上是一个"硬件数据库",内核在启动时读取它来知道"我运行在什么硬件上"。
设备树整体结构图 / (根节点) cpus memory chosen soc uart0 i2c0 cpu@0 cpu@1 节点属性示例 compatible = "arm,cortex-a72"; // 兼容性字符串 reg = <0x0 0x10000000>; // 地址/大小信息 interrupts = <0 33 4>; // 中断描述

1.2 为什么需要设备树

在设备树出现之前(Linux 2.6 ~ 3.x 早期),ARM 架构的硬件描述方式存在严重问题:

  • 硬编码泛滥:每个板级平台都需要在 arch/arm/mach-xxx 下编写大量 C 代码来描述硬件地址、中断号、时钟配置。
  • 内核膨胀:同一份内核需要包含所有支持的板级文件,导致内核镜像体积巨大。
  • 维护噩梦:新增一款硬件需要修改内核源码,社区维护成本呈指数级增长。

设备树解决了以下核心痛点:

痛点设备树方案
硬件描述与内核代码耦合硬件描述独立为 .dts 文件,内核只读取不硬编码
多平台内核镜像过大同一内核二进制 + 不同 DTB 即可适配不同硬件
板级代码重复SoC 级 DTSI 可被多个板级 DTS 复用
外设地址/中断硬编码统一使用 reg、interrupts 属性描述
启动参数传递混乱chosen 节点标准化传递 bootargs、initrd 等
⚠️ 历史教训:在 ARM Linux 社区,设备树的引入被称为"ARM 板级代码的清洗运动"。Linus Torvalds 曾公开批评 ARM 内核的板级代码混乱,设备树是解决这一问题的关键举措。
设备树 vs 传统硬编码方式 传统硬编码方式 arch/arm/mach-xxx/board.c static struct resource uart_res[] = { .start = 0x1C090000, .end = 0x1C090FFF, .flags = IORESOURCE_MEM, }; ❌ 修改硬件需改内核源码 设备树方式 board.dts &uart0 { reg = <0x1C090000 0x1000>; interrupts = <0 33 4>; status = "okay"; }; ✅ 修改硬件只需改 DTS 文件 演进

1.3 设备树与 ACPI 的区别

ACPI(Advanced Configuration and Power Interface)是 x86/x86_64 平台使用的硬件描述标准,与设备树在理念上有本质差异:

对比维度设备树(Device Tree)ACPI
起源Open Firmware(IEEE 1275),PowerPC 平台Intel、Microsoft、Toshiba 联合制定
主要应用平台ARM、RISC-V、PowerPC、MIPSx86、x86_64(PC/服务器)
描述方式静态树形结构,编译为 DTBAML 字节码 + 表结构,支持运行时解释执行
运行时能力静态描述,启动后基本不变(Overlay 除外)支持热插拔、电源管理、动态配置
复杂度轻量,语法简单,易于理解庞大复杂,包含大量表格和方法
内核支持通过 OF 子系统解析通过 ACPI 子系统解析
适用场景嵌入式、IoT、移动设备PC、服务器、工作站
工具链dtc(设备树编译器)iasl(ACPI 源语言编译器)
🔑 核心差异总结:
  • 设备树 = 静态硬件清单:启动时一次性读取,描述"有什么硬件、在哪里"。
  • ACPI = 动态硬件管理层:不仅描述硬件,还包含电源管理、热插拔、设备状态切换等运行时逻辑。
  • 在嵌入式领域,设备树是事实标准;在 PC/服务器领域,ACPI 是强制要求。
设备树 vs ACPI 架构对比 设备树架构 DTS 源文件(人类可读) dtc 编译器 DTB 二进制(内核使用) OF API 解析 → 驱动匹配 ACPI 架构 ASL 源文件(人类可读) iasl 编译器 AML 字节码 + 表结构 ACPI 解释器 → 驱动匹配

1.4 设备树在嵌入式 Linux 中的定位

在典型的嵌入式 Linux 启动流程中,设备树扮演着"硬件翻译官"的角色:

  1. 引导加载程序(U-Boot 等)从存储介质加载 DTB 到内存。
  2. 引导加载程序根据实际硬件情况修改 DTB(如内存大小、MAC 地址)。
  3. 内核启动时通过 of_scan_flat_dt() 解析 DTB,建立设备模型。
  4. 驱动匹配通过 of_match_table 查找 compatible 属性,完成设备绑定。
📌 调试切入点:当外设无法正常工作时,首先检查 DTB 是否正确传递到内核。可以通过内核日志中的 Machine model: 和 OF: fdt: 信息来验证。