4. 根节点与模型:根节点(/)定义、model属性、compatible属性、version属性
设备树(Device Tree)的根节点是整个硬件描述树的起点,它使用斜杠 / 作为节点名称。根节点定义了系统最顶层的硬件模型信息,包括设备兼容性、制造商、版本号等关键标识。内核通过解析根节点的属性,确定当前硬件平台并加载对应的驱动。
4.1 根节点定义与基本结构
根节点是所有设备树节点的祖先,在 DTS 文件中使用 / 表示。根节点内部可以包含子节点(如 CPU、内存、总线等),同时自身携带描述整板信息的属性。
/ {
model = "Qualcomm Technologies, Inc. MSM8998 v2.1";
compatible = "qcom,msm8998", "qcom,msm8998-v2.1";
#address-cells = <2>;
#size-cells = <2>;
chosen { };
memory@80000000 { };
cpus { };
soc { };
};
关键点:根节点没有
reg 属性,因为它不占用任何地址空间。根节点的 #address-cells 和 #size-cells 为整个设备树提供默认地址编码规则。
4.2 model 属性:硬件型号标识
model 属性是一个字符串,用于描述整块开发板或设备的精确型号。该属性通常包含制造商名称、芯片代号和修订版本号,便于开发者和调试工具快速识别硬件。
| 属性 | 格式 | 示例值 | 作用 |
|---|---|---|---|
model |
字符串 | "Qualcomm Technologies, Inc. MSM8998 v2.1" |
精确标识硬件型号与版本 |
compatible |
字符串列表 | "qcom,msm8998", "qcom,msm8998-v2.1" |
驱动匹配与平台识别 |
version |
字符串 | "1.0" |
设备树文件版本号 |
实践建议:
model 字符串应遵循 "制造商,产品名 修订号" 的命名规范,例如 "Samsung, Galaxy S10 5G" 或 "Raspberry Pi Foundation, Raspberry Pi 4 Model B Rev 1.4"。
4.3 compatible 属性:驱动匹配的核心
compatible 属性是设备树中最重要的属性之一,它定义了设备与驱动之间的匹配关系。该属性是一个字符串列表,按优先级从高到低排列。内核在启动时读取根节点的 compatible 值,与注册的 platform_driver 的 of_match_table 进行比对。
// 根节点中的 compatible 定义
compatible = "qcom,msm8998", "qcom,msm8998-v2.1";
// 内核驱动中的匹配表
static const struct of_device_id msm8998_dt_match[] = {
{ .compatible = "qcom,msm8998", },
{ .compatible = "qcom,msm8998-v2.1", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, msm8998_dt_match);
匹配优先级规则:
- 内核优先使用列表中的第一个字符串进行匹配
- 如果第一个匹配失败,依次尝试后续字符串
- 最具体的版本号应放在最前面,通用型号放在后面
- 匹配成功时,驱动可以获取到匹配到的
of_device_id结构体
常见错误:将通用型号放在最前面会导致驱动总是匹配到通用版本,无法区分不同修订版的硬件差异。正确的做法是:
"qcom,msm8998-v2.1", "qcom,msm8998"。
4.4 version 属性:设备树版本管理
version 属性用于标识设备树文件本身的版本号,便于在开发过程中追踪 DTS 文件的变更。虽然该属性不是内核强制要求的,但在大型项目中(如 Android 平台)被广泛使用。
/ {
model = "Qualcomm Technologies, Inc. MSM8998 v2.1";
compatible = "qcom,msm8998", "qcom,msm8998-v2.1";
version = "1.0";
};
version 属性的典型用途:
- 开发阶段:区分不同迭代版本的 DTS 文件
- 调试阶段:快速确认当前使用的设备树版本
- 发布管理:与固件版本号对应,确保设备树与内核匹配
4.5 根节点属性与驱动匹配流程
下图展示了从设备树根节点属性到内核驱动匹配的完整流程:
4.6 根节点属性对比总结
| 属性 | 是否必需 | 参与驱动匹配 | 典型值 | 注意事项 |
|---|---|---|---|---|
model |
推荐 | 否 | "Qualcomm MSM8998 v2.1" |
用于调试和日志输出 |
compatible |
是 | 是 | "qcom,msm8998", "qcom,msm8998-v2.1" |
最具体版本放最前面 |
version |
可选 | 否 | "1.0" |
用于 DTS 版本追踪 |
#address-cells |
是 | 否 | <2> |
定义地址编码宽度 |
#size-cells |
是 | 否 | <2> |
定义大小编码宽度 |
4.7 实战案例:Android 设备根节点配置
以下是一个典型的 Android 手机设备树根节点配置示例,展示了如何组合使用上述属性:
/dts-v1/;
/ {
model = "Xiaomi Technologies, Inc. Mi 8 SE v1.0";
compatible = "xiaomi,sirius", "qcom,sdm710", "qcom,sdm710-v2";
version = "2023.12.01";
#address-cells = <2>;
#size-cells = <2>;
chosen {
bootargs = "console=ttyMSM0,115200n8 earlycon=msm_geni_serial,0xa90000";
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0x80000000>;
};
cpus {
#address-cells = <2>;
#size-cells = <0>;
// CPU 子节点定义...
};
soc {
#address-cells = <2>;
#size-cells = <2>;
// 外设节点定义...
};
};
Android 平台特别说明:在 Android 设备树中,根节点的
compatible 属性通常包含三个层级:板级型号(如 xiaomi,sirius)、SoC 型号(如 qcom,sdm710)、SoC 修订版(如 qcom,sdm710-v2)。这种分层设计使得同一 SoC 的不同设备可以共享驱动,同时保留板级定制能力。
4.8 常见问题与避坑指南
- compatible 顺序错误:将通用型号放在最前面会导致驱动无法区分硬件修订版,应始终将最具体的版本放在首位。
- model 属性缺失:虽然内核不强制要求,但缺少
model属性会导致调试日志中无法识别具体硬件型号。 - version 属性滥用:不要将
version用于驱动匹配逻辑,它仅作为 DTS 文件的元数据存在。 - 根节点地址属性遗漏:如果根节点未定义
#address-cells和#size-cells,子节点将使用默认值<1>,可能导致 64 位地址解析错误。
内核启动调试技巧:当驱动匹配失败时,可以通过内核启动参数
of_devlink 或 dyndbg="file drivers/of/* +p" 开启设备树调试日志,查看内核实际读取的 compatible 值和匹配过程。