3、设备树节点与属性:标准属性详解

设备树中的每个节点都通过一系列属性(Properties)来描述硬件设备的特征、地址、状态和兼容性。在众多属性中,compatible、reg 和 status 是最基础、最核心的标准属性。它们是操作系统识别设备、分配资源以及控制设备启停的关键依据。

核心概念: 设备树属性是键值对(Key-Value Pairs)。键是字符串,值可以是字符串、整数数组、字节串或混合数据。标准属性由 ePAPR 规范定义,所有设备树都必须遵循。

3.1 compatible 属性:设备驱动的“身份证”

compatible 属性是设备树中最重要的属性之一。它指定了设备与设备驱动之间的绑定关系。操作系统通过匹配该属性的字符串值,来寻找能够驱动该设备的驱动程序。

3.1.1 属性格式与匹配规则

compatible 的值是一个字符串列表,通常包含一个“精确型号”和一个“通用兼容型号”。匹配时,操作系统会按照列表中的顺序依次尝试,直到找到匹配的驱动。

// 示例:一个 I2C 触摸控制器节点
touch@38 {
    compatible = "edt,edt-ft5406", "edt,edt-ft5x06";
    reg = <0x38>;
    // ...
};
字符串顺序 字符串值 匹配策略 说明
第一个 "edt,edt-ft5406" 精确匹配 优先使用为该特定型号(FT5406)编写的专用驱动。
第二个 "edt,edt-ft5x06" 兼容匹配 如果没有专用驱动,则使用兼容系列(FT5x06)的通用驱动。
命名规范: 推荐使用 "厂商,型号" 的格式,例如 "ti,am335x-gpio"、"fsl,imx6q-uart"。这可以避免不同厂商之间的命名冲突。

3.1.2 匹配流程示意图

下面的 SVG 图展示了内核从设备树节点到驱动匹配的完整流程。

compatible 属性匹配流程 设备树节点 compatible = "A", "B" OF 核心层 of_match_table 匹配 驱动列表 遍历 .of_match_table 匹配? OK NO 说明:内核优先匹配列表中的第一个字符串,失败后依次尝试后续字符串。

3.2 reg 属性:设备地址空间与资源映射

reg 属性用于描述设备在系统总线上的地址空间。它定义了设备占用的寄存器地址范围、内存区域或 I/O 端口号。该属性是操作系统为设备分配物理地址、建立内存映射(MMIO)的基础。

3.2.1 属性结构与地址描述

reg 的值是一个或多个 地址/长度对(Address/Length Pairs)。每个对由 #address-cells 和 #size-cells 属性决定其长度。

// 示例:一个 SPI 控制器节点
spi@10000000 {
    compatible = "ti,am335x-spi";
    reg = <0x10000000 0x1000>;  // 基地址 0x10000000,长度 0x1000 (4KB)
    interrupts = <0 45 4>;
    // ...
};
字段 值 含义
地址 (Address) 0x10000000 设备在总线上的起始物理地址。
长度 (Size) 0x1000 设备占用的地址空间大小(字节)。

3.2.2 多地址空间与片选

对于具有多个独立地址区域或片选(Chip Select)的设备,reg 可以包含多个地址/长度对。

// 示例:一个具有两个内存区域的设备
memory-controller@20000000 {
    compatible = "vendor,mem-ctrl";
    reg = <0x20000000 0x1000   // 控制寄存器区域
           0x30000000 0x2000>; // 数据缓冲区区域
    // ...
};
关键点: 对于挂接在 #address-cells = <2> 总线上的设备(如 PCIe),地址可能由“高32位 + 低32位”组成,长度也可能由多个 cell 表示。解析时必须根据父节点的 #address-cells 和 #size-cells 进行。

3.3 status 属性:设备状态控制

status 属性用于指示设备的操作状态。它允许在不修改硬件描述的情况下,通过设备树来启用或禁用设备。这对于处理 SoC 中不同型号的变体或修复硬件问题非常有用。

3.3.1 标准状态值

状态值 含义 内核行为
"okay" 设备正常且已启用 内核会尝试初始化并驱动该设备。
"disabled" 设备存在但被禁用 内核会忽略该设备,不会为其创建 platform device 或调用驱动。
"fail" 设备存在但无法操作 内核会识别设备,但不会尝试驱动它(通常用于表示硬件故障)。
"fail-sss" 设备因特定原因失败 sss 是错误码,用于调试。

3.3.2 实际应用场景

在开发板或产品中,经常通过 status 属性来裁剪功能。例如,一个 SoC 内部集成了两个以太网控制器,但产品只需要一个,可以在设备树中将另一个的 status 设置为 "disabled"。

// 在 SoC 的 dtsi 文件中,两个以太网控制器默认都是 "okay"
&mac0 {
    status = "okay";
};

&mac1 {
    status = "okay";
};

// 在板级 dts 文件中,禁用 mac1
&mac1 {
    status = "disabled";
};

3.4 三大标准属性关系总结

下表总结了 compatible、reg 和 status 在设备驱动生命周期中的不同作用。

属性 作用阶段 核心功能 类比
compatible 驱动匹配阶段 告诉内核“我是谁”,用于寻找正确的驱动。 身份证
reg 资源分配阶段 告诉内核“我在哪”,用于分配地址和内存资源。 房产证
status 设备初始化阶段 告诉内核“我是否可用”,用于控制设备的启停。 开关

3.5 综合示例:一个完整的 UART 节点

下面的示例展示了一个典型的 UART 设备树节点,它综合使用了上述三个标准属性。

uart0: serial@44e09000 {
    compatible = "ti,am335x-uart", "ti,omap3-uart";
    reg = <0x44e09000 0x2000>;
    interrupts = <0 72 4>;
    status = "okay";
    clock-frequency = <48000000>;
    // ...
};
实践建议: 在编写设备树时,务必确保 compatible 字符串的精确性,reg 地址与硬件手册一致,并且根据实际需求正确设置 status。这三个属性是设备树调试中最常检查的起点。