4. 根节点与模型属性:根节点定义、model属性、compatible属性的作用与写法

设备树的根节点是整个硬件描述树的起点,所有外设、总线、控制器都作为根节点的子节点存在。根节点本身也携带关键的描述信息,其中 model 和 compatible 是最核心的两个属性,它们决定了操作系统如何识别和匹配硬件平台。

4.1 根节点的定义与结构

在 DTS 文件中,根节点使用 / 表示,所有其他节点都嵌套在根节点内部。根节点没有 node-name 和 unit-address,它直接由花括号包裹整个设备树内容。

/ {
    model = "TI AM335x BeagleBone Black";
    compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";

    chosen { };
    memory { };
    cpus { };
    ocp { };
};
关键点:根节点是设备树的唯一入口,所有节点路径都以 / 开头。根节点下的 chosen、memory、cpus 等子节点是标准约定,用于描述系统级信息。

4.2 model 属性:硬件型号标识

model 属性是一个字符串,用于精确描述开发板或设备的型号名称。它通常由厂商名和板名组成,格式为 "厂商,产品型号"。该属性主要用于人类阅读和调试,操作系统内核在启动时会将其打印到日志中。

属性 值类型 示例 说明
model string "TI AM335x BeagleBone Black" 精确的硬件型号名称,用于识别具体板卡
model string "Raspberry Pi 4 Model B" 树莓派4B的官方型号标识
最佳实践:model 属性应包含厂商名和具体版本号,避免使用模糊名称。例如 "acme,coyote-rev1" 比 "coyote" 更清晰。

4.3 compatible 属性:操作系统匹配核心

compatible 属性是设备树中最重要的属性之一,它是一个字符串列表,用于告诉操作系统该设备(或整个系统)兼容哪些驱动。操作系统内核通过匹配 compatible 字符串来加载对应的设备驱动。

compatible 的格式为 "厂商,设备型号",多个值按优先级从高到低排列。内核会依次尝试匹配,直到找到支持的驱动。

/ {
    compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
};

上述示例中,内核会先尝试匹配 "ti,am335x-bone-black"(最精确),如果失败则尝试 "ti,am335x-bone",最后尝试 "ti,am33xx"(最通用)。

4.4 model 与 compatible 的对比

对比维度 model compatible
用途 人类可读的型号标识 操作系统驱动匹配
值类型 单个字符串 字符串列表(多个值)
匹配方式 不参与匹配,仅用于显示 内核按优先级依次匹配
格式要求 自由格式,建议包含厂商和型号 严格格式:"厂商,设备型号"
是否必须 强烈建议 必须

4.5 根节点属性与内核启动流程

内核在启动过程中,会首先解析根节点的 compatible 属性,确定当前运行的硬件平台,然后加载对应的板级初始化代码。下图展示了根节点属性在内核启动中的关键作用:

根节点属性与内核启动匹配流程 根节点 / model = "板卡型号" compatible = "..." 仅用于日志输出 和调试识别 内核解析 compatible 匹配驱动列表 加载对应驱动

4.6 实际案例:BeagleBone Black 根节点

以 BeagleBone Black 开发板为例,其根节点定义如下:

/ {
    model = "TI AM335x BeagleBone Black";
    compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";

    chosen {
        stdout-path = &uart0;
    };

    memory@80000000 {
        device_type = "memory";
        reg = <0x80000000 0x10000000>; /* 256 MB */
    };

    cpus {
        cpu@0 {
            compatible = "arm,cortex-a8";
        };
    };
};
常见错误:compatible 属性中厂商名和设备名之间必须使用逗号分隔,且不能有空格。例如 "ti,am33xx" 正确,"ti am33xx" 错误。内核驱动匹配时严格按字符串比较,格式错误会导致驱动无法加载。

4.7 根节点属性编写规范

  • model 属性:每个设备树文件都应包含 model 属性,格式为 "厂商,产品型号",便于开发和调试人员识别硬件。
  • compatible 属性:必须包含至少一个值,且第一个值应为最精确的型号匹配。后续值按兼容性从高到低排列,确保内核能找到合适的驱动。
  • 命名规范:厂商名使用小写字母,设备型号使用小写字母和连字符,例如 "ti,am335x-bone-black"。
  • 版本管理:当硬件版本升级时,应更新 compatible 列表,保留旧版本兼容值,确保向后兼容。

4.8 根节点属性与设备树包含机制

在实际项目中,根节点通常定义在 .dts 文件中,而 .dtsi 文件(设备树包含文件)只定义部分节点。根节点的 model 和 compatible 属性应在最顶层的 .dts 文件中定义,避免在多个 .dtsi 文件中重复定义导致冲突。

/* am335x-bone-common.dtsi */
/ {
    chosen { };
    memory { };
    cpus { };
    /* 不定义 model 和 compatible */
};

/* am335x-boneblack.dts */
#include "am335x-bone-common.dtsi"

/ {
    model = "TI AM335x BeagleBone Black";
    compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
};
工程建议:将公共硬件描述放在 .dtsi 文件中,将板级特定的 model 和 compatible 放在 .dts 文件中。这样当同一 SoC 有多个不同板卡时,只需修改 .dts 文件即可。