2. 设备树节点与属性:节点命名规则、标准属性详解

设备树(Device Tree,DT)是嵌入式 Linux 中用于描述硬件拓扑结构的数据结构。它通过节点(Node)和属性(Property)将非可枚举的硬件信息传递给内核。本章将深入讲解节点的命名规范以及三个最核心的标准属性:compatible、reg 和 status。

学习目标:掌握设备树节点的合法命名规则;理解 compatible 属性在驱动匹配中的核心作用;学会使用 reg 属性描述地址空间;掌握 status 属性控制设备启用/禁用的方法。

2.1 节点命名规则

设备树中的每个节点都必须遵循严格的命名规范,以确保解析器能够正确识别。节点名由两部分组成:节点名称和可选的单元地址。

2.1.1 基本格式

node-name@unit-address
  • node-name:描述设备通用类型,必须使用小写字母、数字、连字符(-)或下划线(_)组成,长度不超过 31 个字符。例如:uart、i2c、gpio-controller。
  • @unit-address:可选部分,用于区分同一总线上的多个同类型设备。通常为设备在父总线上的起始地址(十六进制)。例如:serial@101f0000。

2.1.2 命名规则速查表

规则项 要求 合法示例 非法示例
字符集 小写字母、数字、连字符、下划线 spi-controller SPI_CTRL(大写)
长度限制 ≤ 31 个字符 ethernet-phy@0 very-long-device-name-example@0(超长)
单元地址 十六进制,无 0x 前缀 uart@1c28000 uart@0x1c28000
根节点 固定为 / / 无

2.1.3 节点命名与设备类型对应关系

为了保持设备树的可读性,社区推荐使用标准化的节点名称。以下为常见设备类型与其推荐节点名的对照表:

设备类型 推荐节点名 说明
CPU cpu 每个 CPU 核心一个子节点
内存 memory 描述物理内存布局
中断控制器 interrupt-controller GIC、INTC 等
GPIO 控制器 gpio-controller 通用 GPIO 模块
串口 serial UART 设备
I2C 控制器 i2c I2C 总线适配器
SPI 控制器 spi SPI 总线适配器
以太网 ethernet MAC 层控制器
最佳实践:在编写设备树时,优先使用上述推荐节点名。如果设备类型不在列表中,使用 generic-device 格式,并确保 compatible 属性足够具体以区分硬件。
设备树节点命名结构图 / cpu@0 node-name@unit-address memory node-name(无地址) serial@1c28000 node-name@unit-address 命名规则要点 node-name:小写字母、数字、连字符,≤31字符 unit-address:十六进制地址,无 0x 前缀,用于区分同类型设备

2.2 标准属性详解

设备树属性是键值对,用于描述节点的特征。以下三个属性是所有设备树节点中最基础、最常用的标准属性。

2.2.1 compatible 属性:驱动匹配的桥梁

compatible 属性是设备树与内核驱动之间建立关联的核心机制。它包含一个或多个字符串,用于指定设备所兼容的硬件型号。

语法格式:

compatible = "manufacturer,model", "fallback-model";
  • 第一个字符串:精确的硬件型号,格式为 "厂商,设备型号"。例如:"ti,am3359-uart"。
  • 后续字符串:兼容的通用型号,用于驱动回退匹配。例如:"ns16550a"。

匹配优先级:内核在注册平台驱动时,会按照 of_match_table 中定义的顺序与设备树的 compatible 列表进行匹配。匹配顺序为:精确匹配 → 回退匹配。

匹配类型 设备树 compatible 驱动 of_match_table 匹配结果
精确匹配 "ti,am3359-uart" "ti,am3359-uart" ✅ 匹配成功
回退匹配 "ti,am3359-uart", "ns16550a" "ns16550a" ✅ 匹配成功(回退)
不匹配 "ti,am3359-uart" "snps,dw-apb-uart" ❌ 匹配失败
常见错误:compatible 字符串中厂商名和设备名之间必须使用逗号分隔,且逗号后不能有空格。例如:"ti,am3359-uart" 正确,"ti, am3359-uart" 错误。

2.2.2 reg 属性:地址空间描述

reg 属性用于描述设备在父总线上的地址空间。它由一组或多组 (address, length) 对组成,具体含义由父节点的 #address-cells 和 #size-cells 属性决定。

语法格式:

reg = <address1 length1 address2 length2 ...>;

地址单元与大小单元:

父节点属性 含义 常见值
#address-cells 地址字段占用的 32 位单元数 1(32位地址)或 2(64位地址)
#size-cells 长度字段占用的 32 位单元数 1(32位长度)或 0(无长度)

示例解析:

// 父节点定义
soc {
    #address-cells = <1>;   // 地址为 32 位
    #size-cells    = <1>;   // 长度为 32 位

    uart@1c28000 {
        compatible = "snps,dw-apb-uart";
        reg = <0x1c28000 0x1000>;  // 起始地址 0x1c28000,长度 0x1000
        interrupts = <0 39 4>;
    };
};

上述示例中,reg = <0x1c28000 0x1000> 表示 UART 设备占用从物理地址 0x1c28000 开始的 0x1000(4KB)地址空间。

2.2.3 status 属性:设备状态控制

status 属性用于指示设备的启用状态。它允许在不修改硬件描述的情况下,通过设备树覆盖来启用或禁用设备。

status 值 含义 使用场景
"okay" 设备已启用且功能正常 默认启用状态
"disabled" 设备被禁用,内核不会为其创建平台设备 硬件存在但未使用,或需要由其他固件配置
"reserved" 设备已被保留,内核不应使用 由安全固件或 Hypervisor 占用
"fail" 设备检测失败,不可用 硬件自检未通过
"fail-sss" 设备因特定原因失败,sss 为错误码 提供更详细的失败原因
覆盖机制:在设备树包含(include)或叠加(overlay)中,可以通过重新定义 status 属性来改变设备状态。例如,在基础设备树中设置 status = "disabled",在板级设备树中覆盖为 status = "okay"。
标准属性工作流程图 设备树节点 uart@1c28000 compatible "snps,dw-apb-uart" 驱动匹配 of_match_table 查找 reg <0x1c28000 0x1000> 地址映射 ioremap 资源分配 status "okay" 设备启用 platform_device 注册 设备正常工作

2.3 综合示例:完整的中断控制器节点

以下是一个包含上述所有标准属性的实际设备树节点示例,展示了一个 ARM GIC(通用中断控制器)的典型描述:

// 中断控制器节点
intc: interrupt-controller@1c81000 {
    compatible = "arm,cortex-a9-gic";
    #interrupt-cells = <3>;          // 每个中断描述占用 3 个单元
    #address-cells = <0>;            // 无子地址
    interrupt-controller;             // 标记为中断控制器
    reg = <0x1c81000 0x1000>,        // GIC 分配器寄存器
          <0x1c82000 0x2000>;        // GIC CPU 接口寄存器
    status = "okay";                  // 设备启用
};
关键点:
  • compatible = "arm,cortex-a9-gic" 确保内核使用正确的 GIC 驱动。
  • reg 包含两段地址空间:分配器(Distributor)和 CPU 接口(CPU Interface)。
  • status = "okay" 明确告知内核该中断控制器已就绪。

2.4 本章小结

  • 节点命名:遵循 node-name@unit-address 格式,名称使用小写字母和连字符,地址为十六进制无前缀。
  • compatible:驱动匹配的核心,使用 "厂商,型号" 格式,支持回退匹配。
  • reg:描述地址空间,由 #address-cells 和 #size-cells 决定格式。
  • status:控制设备启用/禁用,支持通过设备树覆盖进行动态调整。
课后练习:编写一个 SPI 控制器的设备树节点,要求:节点名为 spi@1c05000,compatible 为 "snps,dw-apb-ssi",reg 地址范围为 0x1c05000 长度 0x1000,状态为启用。