3. 设备树基础语法:DTS/DTC/DTB 概念、节点与属性

设备树(Device Tree)是嵌入式 Linux 中用于描述硬件拓扑结构的关键机制。在全志 T113 平台上,设备树文件决定了内核如何识别 CPU、内存、外设控制器以及 GPIO 引脚功能。本章将系统讲解设备树的核心概念、语法结构以及关键属性,为后续的 GPIO 驱动开发打下坚实基础。

学习目标:掌握 DTS → DTB 的编译流程;理解节点(node)与属性(property)的层级关系;熟练使用 #address-cells、#size-cells、reg、compatible 等核心属性。

3.1 DTS / DTC / DTB 概念与编译流程

设备树源文件(.dts)通过设备树编译器(DTC)编译为二进制设备树 blob(.dtb),U-Boot 或内核在启动时解析 DTB 以获取硬件信息。

DTS → DTC → DTB 编译与加载流程 DTS 源文件 sun8i-t113-mangopi.dts DTC 编译器 dtc -I dts -O dtb DTB 二进制 sun8i-t113.dtb U-Boot 加载 DTB 内核解析 DTB 驱动匹配硬件 DTS 是文本源文件,DTC 是编译器,DTB 是内核最终使用的二进制描述
设备树文件类型对比
文件类型扩展名格式作用
DTS.dts文本(ASCII)设备树源文件,开发者编写硬件描述
DTSI.dtsi文本(ASCII)设备树包含文件,用于 SoC 级公共定义
DTB.dtb二进制编译后的设备树,内核/U-Boot 直接使用
DTC—可执行程序设备树编译器,将 DTS 转换为 DTB
实战命令:在全志 T113 开发环境中,使用 dtc -I dts -O dtb -o sun8i-t113.dtb sun8i-t113.dts 完成编译;使用 dtc -I dtb -O dts -o decompiled.dts sun8i-t113.dtb 反编译验证。

3.2 节点(Node)与属性(Property)

设备树由树状结构的节点组成,每个节点代表一个硬件设备或总线,节点内包含若干属性来描述设备特征。

设备树节点层级结构示例 / (根节点) soc@1c00000 uart0@1c28000 pio@1c20800 i2c0@1c2ac00 led@0 (子节点) 每个节点可包含子节点 形成树形硬件拓扑

节点命名规则:节点名@单元地址,其中单元地址通常对应设备在总线上的起始地址。例如 uart0@1c28000 表示 UART0 控制器,其寄存器基地址为 0x01c28000。

属性类型:

  • 字符串:compatible = "allwinner,sun8i-t113-uart";
  • 32 位整数:reg = <0x01c28000 0x400>;
  • 64 位整数(双 32 位):reg = <0x00000000 0x40000000 0x00000000 0x20000000>;
  • 布尔值:status = "okay"; 或 status = "disabled";
  • 字节数组:local-mac-address = [00 11 22 33 44 55];

3.3 #address-cells 与 #size-cells

这两个属性定义了 reg 属性中地址和长度字段的宽度(以 32 位字为单位)。

#address-cells / #size-cells 取值含义
属性取值含义
#address-cells1地址字段占 1 个 32 位字(32 位地址空间)
#address-cells2地址字段占 2 个 32 位字(64 位地址空间)
#size-cells1长度字段占 1 个 32 位字(最大 4GB 范围)
#size-cells0长度字段为空(仅表示地址,无范围)
常见错误:在全志 T113 的 soc 节点中,#address-cells = <1> 且 #size-cells = <1>,因为 T113 的 32 位地址空间使用单字表示。如果错误设置为 2,会导致内核解析 reg 时读取错误的地址值,造成驱动无法匹配。
#address-cells / #size-cells 对 reg 的解析影响 #address-cells = 1, #size-cells = 1 reg = <0x1c28000 0x400> → 地址:0x1c28000 长度:0x400 #address-cells = 2, #size-cells = 1 reg = <0x0 0x1c28000 0x400> → 64位地址+32位长度 T113 使用 32 位地址空间,因此 #address-cells = 1;若为 64 位 SoC(如 AArch64),则 #address-cells = 2 #size-cells = 0 常用于 GPIO 控制器等无内存映射的设备

3.4 reg 属性

reg 属性描述设备的地址空间信息,格式为 reg = <地址1 长度1 地址2 长度2 ...>。每个地址-长度对称为一个 region,表示设备占用的连续地址范围。

// 全志 T113 UART0 节点示例
uart0: serial@1c28000 {
    compatible = "allwinner,sun8i-t113-uart", "allwinner,sun6i-a31-uart";
    reg = <0x01c28000 0x400>;          // 基地址 0x01c28000,长度 0x400
    interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&ccu CLK_BUS_UART0>;
    status = "disabled";
};

// 多 region 示例(如 SPI 控制器带两个地址块)
spi0: spi@1c68000 {
    compatible = "allwinner,sun8i-t113-spi";
    reg = <0x01c68000 0x1000>,        // 主寄存器块
          <0x01c69000 0x100>;          // 辅助 FIFO 块
    #address-cells = <1>;
    #size-cells = <0>;
};
全志 T113 关键外设 reg 地址速查:
  • PIO(GPIO 控制器):0x01c20800,长度 0x400
  • UART0:0x01c28000,长度 0x400
  • I2C0:0x01c2ac00,长度 0x400
  • SPI0:0x01c68000,长度 0x1000

3.5 compatible 属性

compatible 是设备树中最关键的属性之一,用于将设备节点与内核驱动进行匹配。其值为字符串列表,按优先级从高到低排列。

compatible 属性匹配规则
匹配方式示例说明
精确匹配"allwinner,sun8i-t113-uart"驱动中 of_match_table 完全匹配该字符串
兼容匹配"allwinner,sun6i-a31-uart"如果精确匹配失败,内核尝试兼容匹配(回退方案)
通配匹配"simple-bus"用于总线节点,内核自动枚举子节点
compatible 属性驱动匹配流程 设备节点 compatible = "A", "B", "C" 内核匹配层 遍历 of_match_table 匹配成功 调用 probe() 函数 匹配失败 尝试下一个 compatible 值 全志 T113 的 GPIO 控制器 compatible 为 "allwinner,sun8i-t113-pio",驱动在 pinctrl-sun8i.c 中匹配
// 全志 T113 GPIO 控制器节点(PIO)的 compatible 定义
pio: pinctrl@1c20800 {
    compatible = "allwinner,sun8i-t113-pio";
    reg = <0x01c20800 0x400>;
    interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&ccu CLK_BUS_PIO>;
    gpio-controller;
    #gpio-cells = <3>;
    interrupt-controller;
    #interrupt-cells = <3>;
};
驱动匹配优先级:内核按照 of_match_table 中定义的顺序进行匹配。建议将最精确的 compatible 字符串放在最前面,通用兼容字符串放在后面。例如 "allwinner,sun8i-t113-pio" 优先于 "allwinner,sun8i-h3-pio"。

3.6 本章小结

核心概念速查表
概念关键点全志 T113 典型值
DTS → DTB通过 DTC 编译,U-Boot 加载sun8i-t113.dts → sun8i-t113.dtb
节点命名节点名@单元地址pinctrl@1c20800
#address-cells地址字段宽度(32 位字)1(32 位地址空间)
#size-cells长度字段宽度(32 位字)1(最大 4GB)
reg地址-长度对,描述硬件地址空间<0x01c20800 0x400>
compatible驱动匹配字符串,支持多级回退"allwinner,sun8i-t113-pio"