4. 设备树(DT)基础回顾:设备树语法、节点与属性

设备树(Device Tree, DT)是嵌入式系统中用于描述硬件拓扑结构的数据结构,它使得同一份内核镜像能够支持多种硬件平台。在从 ARM 向 RISC-V 移植驱动时,设备树是解耦硬件描述与内核代码的关键桥梁。本节将系统回顾设备树的核心语法、节点与属性定义,以及 .dts、.dtsi、.dtb 文件之间的关系。

4.1 设备树语法基础

设备树源文件(.dts)采用树形结构描述硬件,每个硬件设备对应一个节点(node),节点内包含若干属性(property)描述设备的配置信息。其基本语法规则如下:

  • 节点定义:node-name@unit-address,其中 unit-address 通常为设备基地址。
  • 属性赋值:property-name = <value>; 或 property-name = "string";。
  • 标签(label):label: node-name@address,用于在其它位置引用节点。
  • 包含文件:#include "filename.dtsi",用于复用通用硬件描述。
关键点:设备树不是编程语言,而是纯数据描述语言。它不包含控制流或函数调用,所有信息均为静态硬件配置。

4.1.1 节点与属性示例

/dts-v1/;

/ {
    compatible = "acme,coyote-revenge";

    cpus {
        #address-cells = <1>;
        #size-cells = <0>;

        cpu@0 {
            compatible = "arm,cortex-a9";
            reg = <0>;
            device_type = "cpu";
        };
    };

    memory@80000000 {
        device_type = "memory";
        reg = <0x80000000 0x40000000>;  /* 1 GB at 0x80000000 */
    };

    serial@101f1000 {
        compatible = "ns16550";
        reg = <0x101f1000 0x1000>;
        interrupts = <5>;
        interrupt-parent = <&gic>;
    };
};
提示:#address-cells 和 #size-cells 定义子节点中 reg 属性的地址和长度字段宽度。在 RISC-V 平台上,这两个值通常为 <2> 和 <2>,以支持 64 位地址空间。

4.2 标准属性详解

设备树规范定义了一组标准属性,用于描述设备的核心特征。以下三个属性在驱动移植中最为关键:

属性名 作用 格式 示例
compatible 指定设备兼容的驱动名称,内核通过此属性匹配驱动 "manufacturer,model" "ti,am3352-uart"
reg 描述设备在总线上的地址空间(基地址 + 长度) <address length> <0x10000000 0x1000>
interrupts 描述设备使用的中断号及触发类型 <interrupt-specifier> <0 3 4>(SPI 中断号 3,高电平触发)

4.2.1 compatible 属性与驱动匹配

compatible 是驱动与设备绑定的核心依据。内核的 of_match_table 会遍历设备树节点的 compatible 字符串列表,找到匹配的驱动。在 ARM 到 RISC-V 移植中,通常需要修改 compatible 字符串以反映新平台的厂商和型号。

/* ARM 平台 */
compatible = "arm,pl011", "arm,primecell";

/* RISC-V 平台 */
compatible = "sifive,uart0", "sifive,uart";

4.2.2 reg 属性与地址映射

reg 属性定义了设备的物理地址范围。驱动通过 of_iomap() 或 platform_get_resource() 获取该地址并建立映射。在 RISC-V 平台上,由于地址空间可能更大,#address-cells 通常设为 2。

注意:移植时务必检查 reg 中的地址值是否与 RISC-V 平台的 memory 节点和 soc 总线地址空间一致。错误的地址映射会导致内核 panic。

4.2.3 interrupts 属性与中断控制器

interrupts 属性指定设备连接的中断线。其格式由父中断控制器(interrupt-parent)的 #interrupt-cells 决定。ARM 平台常用的 GIC(Generic Interrupt Controller)与 RISC-V 平台常用的 PLIC(Platform-Level Interrupt Controller)在中断描述上存在显著差异:

中断控制器 #interrupt-cells 中断描述格式 示例
ARM GIC 3 <中断类型 中断号 触发方式> <0 42 4>(SPI, 中断号42, 高电平触发)
RISC-V PLIC 1 <中断号> <10>(中断号10)

4.3 dts / dtsi / dtb 文件关系

设备树源文件通过编译生成二进制 .dtb 文件,供内核在启动时解析。理解三种文件类型的关系是高效管理设备树的基础。

设备树文件关系与编译流程 .dtsi 通用硬件描述(SoC 内核) .dts 板级硬件描述(外设 + 引脚) .dtb 二进制设备树(内核加载) #include dtc 编译 文件关系说明: • .dtsi:类似 C 语言头文件,定义 SoC 内部通用硬件(CPU、中断控制器、时钟等)。 • .dts:板级文件,通过 #include 引用 .dtsi,并添加板级外设、引脚复用、内存布局等。 • .dtb:由 dtc(Device Tree Compiler)将 .dts 编译生成的二进制文件,内核在启动时解析。

4.3.1 文件组织最佳实践

  • 分层设计:将 SoC 级通用描述放在 .dtsi 中,板级差异放在 .dts 中,避免重复。
  • 覆盖机制:.dts 可以覆盖 .dtsi 中定义的节点属性,实现板级定制。
  • 多级包含:RISC-V 平台常采用 soc.dtsi → board.dtsi → my-board.dts 的层级结构。
/* riscv-soc.dtsi - 通用 RISC-V SoC 描述 */
/ {
    cpus { ... };
    soc {
        plic: interrupt-controller@c000000 {
            compatible = "sifive,plic-1.0.0";
            reg = <0x0 0xc000000 0x0 0x4000000>;
            interrupt-controller;
            #interrupt-cells = <1>;
        };
        uart0: serial@10010000 {
            compatible = "sifive,uart0";
            reg = <0x0 0x10010000 0x0 0x1000>;
            interrupt-parent = <&plic>;
            interrupts = <3>;
        };
    };
};

/* my-board.dts - 板级文件 */
/dts-v1/;
#include "riscv-soc.dtsi"

/ {
    model = "My RISC-V Board";
    compatible = "mycompany,myboard";

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

    &uart0 {
        status = "okay";
        clock-frequency = <3686400>;
    };
};

4.4 设备树在驱动移植中的核心作用

在 ARM 到 RISC-V 的驱动移植过程中,设备树承担以下关键职责:

  1. 硬件描述解耦:将硬件配置信息从内核代码中剥离,使同一份驱动可适配不同平台。
  2. 中断控制器抽象:通过 interrupt-parent 和 interrupts 属性,驱动无需关心底层中断控制器类型(GIC vs PLIC)。
  3. 地址空间映射:reg 属性提供物理地址,驱动通过 platform_get_resource() 获取,无需硬编码。
  4. 时钟与复位管理:通过 clocks、resets 等属性描述设备依赖关系。
移植要点:修改设备树时,优先检查 compatible 字符串是否被目标 RISC-V 平台驱动支持;若不支持,需在驱动中新增匹配项。同时,确保 reg 地址和 interrupts 格式与 RISC-V 中断控制器规范一致。

4.5 本章小结