1、设备树基础:什么是设备树、为什么需要设备树、设备树的历史与演进

1.1 什么是设备树?

设备树,英文叫 Device Tree,简称 DT。

说白了,它就是一个描述硬件信息的数据结构。用树形的方式,把 CPU、内存、外设、中断控制器这些东西的配置信息,全部写在一个文本文件里。

我刚开始接触嵌入式 Linux 时,觉得这玩意儿挺玄乎。后来发现,它其实就是一张「硬件清单」。内核启动时,通过这张清单就知道板子上有什么硬件、怎么访问它们。

举个例子,一个简单的设备树节点长这样:

/ {
    model = "MyBoard v1.0";
    compatible = "vendor,myboard", "vendor,common";

    memory@80000000 {
        device_type = "memory";
        reg = <0x80000000 0x20000000>;  // 512MB 内存
    };

    uart0: serial@10000000 {
        compatible = "ns16550";
        reg = <0x10000000 0x1000>;
        interrupts = <0 5 4>;
        clock-frequency = <1843200>;
    };
};

看到没?每个硬件设备就是一个节点。节点里有属性,描述它的地址、中断号、时钟频率等信息。

嗯,这里要注意:设备树不是代码,它只是数据。内核解析它,然后初始化对应的驱动。

1.2 为什么需要设备树?

你可能会问:以前没有设备树,不也跑得好好的吗?

确实,早期的 Linux 内核,硬件信息是硬编码在源码里的。每个板子都要改 arch/arm/mach-xxx 下面的文件。我当年维护过一个项目,光板级文件就有十几个,每个文件里都是 platform_device 结构体数组。

那问题来了:

  • 代码膨胀:每个板子都要写一堆重复的板级文件
  • 维护噩梦:换一个 GPIO 引脚,要改好几个文件
  • 碎片化严重:厂商各自为政,内核主线很难统一支持

我在一个项目中就吃过这个亏。客户要求换一颗 Flash 芯片,我本以为改个分区表就行。结果发现板级文件里硬编码了 Flash 的基地址和大小,还得改内存映射。折腾了两天才搞定。

设备树解决了这些问题:

  • 硬件描述与内核分离:换硬件,改 dts 文件就行,不用重新编译内核
  • 统一规范:所有厂商都按同一套规则写设备树
  • 可复用:一个 SoC 的设备树,可以衍生出多个板级变体

核心思想:设备树把「硬件是什么」和「驱动怎么用」分开了。内核只关心驱动逻辑,硬件细节交给设备树。

1.3 设备树的历史与演进

设备树不是 Linux 原创的。它最早来自 Open Firmware,是 Sun 公司搞出来的东西。PowerPC 架构一直在用。

Linux 内核在 2005 年左右开始引入设备树。我记得当时 Linus Torvalds 对 ARM 架构的板级文件泛滥非常不满,直接开喷说「这简直是垃圾」。嗯,原话更狠。

从那以后,ARM 社区开始推动设备树的普及。到了 2011 年左右,ARM 主线内核正式要求新平台必须使用设备树。

演进过程大致是这样的:

时间 事件
2005 PowerPC 率先在 Linux 中使用设备树
2008 ARM 社区开始讨论引入设备树
2011 ARM 主线内核强制要求设备树
2013 设备树规范 v0.1 发布
2016 设备树覆盖大部分 ARM 平台
至今 RISC-V、x86 等架构也开始使用

我个人习惯把设备树的演进分成三个阶段:

  1. 混沌期:各玩各的,板级文件满天飞
  2. 统一期:设备树成为标准,但写法还很混乱
  3. 成熟期:有了规范、绑定文档、校验工具

避坑指南:我曾经在移植内核时,发现设备树里写的中断号跟芯片手册对不上。查了半天,原来是设备树绑定的中断控制器索引方式跟驱动预期的不一致。所以,写设备树时一定要对照芯片手册和绑定文档,别想当然。

1.4 设备树的核心文件

实际开发中,你会接触到这些文件:

  • .dts:设备树源文件,文本格式,可读性强
  • .dtsi:设备树头文件,通常放 SoC 公共部分
  • .dtb:编译后的二进制文件,内核直接使用
  • .dtbo:设备树叠加层,用于动态修改

编译命令也很简单:

# 将 dts 编译成 dtb
dtc -I dts -O dtb -o myboard.dtb myboard.dts

# 反编译 dtb 查看内容
dtc -I dtb -O dts -o myboard.dts myboard.dtb

你想想看,有了设备树,换一个板子只需要换一个 .dts 文件。内核镜像可以通用,这多方便。

好了,这一章就到这里。设备树不是什么高深的东西,它就是一张硬件配置表。理解了这一点,后面的内容就好办了。