> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 设备树架构

Qualcomm<sup>®</sup> Linux 内核使用分层的设备树(DT)架构,其中平台特定的硬件描述与 SoC 级配置相互分离。
在启动时,UEFI 固件通过将硬件检测到的标识符与 `compatible` 字符串进行匹配,从 FIT 镜像中选择正确的 DTB。

## DTS 和 DTSI 文件结构

设备树源文件位于内核源码树的 `arch/arm64/boot/dts/qcom/` 目录下。

**表:设备树文件类型**

| 文件类型    | 用途                                                                   |
| ------- | -------------------------------------------------------------------- |
| `.dtsi` | SoC 级或共享的硬件描述。由板级 DTS 文件包含。                                          |
| `.dts`  | 板级文件。包含一个或多个 DTSI 文件,并添加板级特定节点,如 pinmux 设置、稳压器和板载外设。                 |
| `.dtb`  | 由 DTS 文件编译生成的二进制输出。在运行时由引导加载程序加载。                                    |
| `.dtbo` | 设备树覆盖(overlay)二进制文件。应用在基础 DTB 之上,用于启用可选的硬件配置,例如夹层板(mezzanine board)。 |

## 板级与 SoC 分层

Qualcomm Linux 遵循严格的两层分层约定:

1. **SoC DTSI**(例如 `qcs6490.dtsi`),定义时钟、电源域、中断控制器以及使用该 SoC 的所有单板通用的核心外设。

2. **板级 DTS**(例如 `qcs6490-rb3gen2.dts`),包含 SoC DTSI 并添加板级特定节点:GPIO 分配、稳压器数值、板载传感器和显示面板。

典型的板级 DTS 以如下内容开头:

```dts theme={null}
#include <dt-bindings/...>
#include "qcs6490.dtsi"

/ {
    model = "Qualcomm QCS6490 Dragonwing™ RB3 Gen2";
    compatible = "qcom,qcs6490-rb3gen2", "qcom,qcs6490";
    /* ... additional board-specific nodes ... */
};
```

## 基于 FIT 的 DTB 打包

Qualcomm Linux 在单个软件发布版本中支持多个 SoC 和单板。DTB 被打包到一个 Flattened Image Tree(FIT)镜像(`qclinux_fit.img`)中,存储在 `dtb_a` 分区。UEFI 固件在启动时通过将硬件检测到的标识符与每个 FIT 配置条目的 `compatible` 字符串进行匹配来选择正确的 DTB。

FIT 镜像由 Image Tree Source(`.its`)文件描述,并使用 `mkimage` 构建。它包含两个顶层部分:

* `images`,声明所有二进制数据块:DTB、DTBO 以及元数据二进制文件。
* `configurations`,声明所有平台配置,每个配置引用一个或多个镜像。

一个最简的 ITS 骨架:

```text theme={null}
/dts-v1/;
/ {
    images {
        /* metadata maps config compatible strings to hardware IDs */
        fdt-qcom-metadata.dtb {
            data = /incbin/("./qcom-metadata.dtb");
            type = "qcom_metadata";
        };
        fdt-<soc>-<board>.dtb {
            data = /incbin/("./arch/arm64/boot/dts/qcom/<soc>-<board>.dtb");
            type = "flat_dt";
        };
    };
    configurations {
        conf-1 {
            compatible = "qcom,<soc>-<board>";
            fdt = "fdt-<soc>-<board>.dtb";
        };
        /* Base DTB + software overlay (CamX) + hardware overlay */
        conf-2 {
            compatible = "qcom,qcs9075-iot-camx-el2kvm";
            fdt = "fdt-lemans-evk.dtb",
                  "fdt-lemans-evk-camx.dtbo",
                  "fdt-lemans-el2.dtbo";
        };
    };
};
```

### Qualcomm DTB 元数据

[qcom-dtb-metadata](https://github.com/qualcomm-linux/qcom-dtb-metadata)
项目提供:

* `qcom-metadata.dts` 编译为元数据 DTB,固件使用它将硬件标识符映射到 FIT 配置的 `compatible` 字符串。
* `qcom-next-fitimage.its` 是用于独立构建的 ITS 模板。

元数据 DTS 将允许的 `compatible` 字符串后缀标记(token)分组到以下节点中:
`soc`、`soc-sku`、`socver`、`board`、`boardrev`、`board-subtype-*`、`softsku`
和 `oem`。

### 启动时的 DTB 选择流程

1. UEFI 从 `dtb_a` 分区加载 `qclinux_fit.img`。
2. 解析嵌入的 `qcom-metadata.dtb`,构建一个将硬件数字 ID 映射到 `compatible` 字符串中使用的符号标记名称的表。
3. 读取硬件标识符:SoC 芯片 ID/版本、来自配置数据表(CDT)的单板类型和修订版本、存储类型以及 DDR 容量。
4. 按顺序遍历 FIT 配置(`conf-1`、`conf-2`、…)。
5. 对于每个配置,将其 `compatible` 字符串中的每个标记与硬件推导出的值进行精确匹配。选择所有标记均匹配的第一个配置。
6. 加载所选配置的 DTB,并通过 EFI 启动传递给操作系统。
7. 如果没有配置匹配,则启动失败。诊断步骤请参阅
   [常见 DT 问题与修复](./common-dt-issues#no-dtb-loaded--fit-configuration-match-failure)。

### Compatible 字符串格式

每个 FIT 配置的 `compatible` 字符串以短横线分隔的标记编码平台标识:

```text theme={null}
qcom,<soc>[-<soc-sku>][-<socver>]-<board>[-<boardrev>]
          [-<peripheral-subtype>][-<storage-type>][-<memory-size>]
          [-<softsku>][-<oem>]
```

省略某个标记表示该维度不受约束,即它匹配该字段的任何硬件值。在 `configurations` 块中,更具体的字符串应出现在通用字符串之前。

**示例:**

```text theme={null}
qcom,qcm6490-idp                 # SoC + board only (matches all revisions)
qcom,qcs9100-qam-r1.0            # SoC + board + explicit board revision
qcom,qcs6490-iot-subtype2        # SoC + board + peripheral subtype
```

## 将 DTB 接入 FIT 镜像(Yocto)

Yocto 构建从两个输入生成 FIT 镜像:

* `KERNEL_DEVICETREE` 和 `LINUX_QCOM_KERNEL_DEVICETREE` 表示要打包到 `images` 部分的 DTB 和 DTBO 列表。
* `conf/machine/include/fit-dtb-compatible.inc` 中的 `FIT_DTB_COMPATIBLE` 条目枚举 `configurations` 部分的条目,这些条目将某个 DTB(或 DTB+DTBO 组合)映射到 UEFI 在启动时要匹配的硬件 `compatible` 字符串。

```text theme={null}
# Upstream DTBs and DTBOs
KERNEL_DEVICETREE ?= " \
    qcom/qcs6490-rb3gen2.dtb \
    qcom/qcs6490-rb3gen2-industrial-mezzanine.dtbo \
    qcom/qcs6490-rb3gen2-vision-mezzanine.dtbo \
    "

# Downstream-only DTBOs (not yet upstreamed)
LINUX_QCOM_KERNEL_DEVICETREE ?= " \
    qcom/qcs6490-rb3gen2-vision-mezzanine-camx.dtbo \
    "
```

### FIT\_DTB\_COMPATIBLE 条目

每个条目将一个 DTB 键(或以 `+` 作为分隔符的 `DTB+DTBO` 键)映射到一个或多个 `compatible` 字符串:

**没有覆盖的单个 DTB:**

```text theme={null}
FIT_DTB_COMPATIBLE[qcs6490-rb3gen2] = " \
    qcom,qcs5430-iot \
    qcom,qcs6490-iot \
    "
```

**DTB + DTBO 组合:**

```text theme={null}
FIT_DTB_COMPATIBLE[qcs6490-rb3gen2+qcs6490-rb3gen2-vision-mezzanine] = " \
    qcom,qcs5430-iot-subtype2 \
    qcom,qcs6490-iot-subtype2 \
    "
```

**同一基础 DTB 的多种组合:**

```text theme={null}
FIT_DTB_COMPATIBLE[qcs6490-rb3gen2] = " \
    qcom,qcs5430-iot \
    qcom,qcs6490-iot \
    "
FIT_DTB_COMPATIBLE[qcs6490-rb3gen2+qcs6490-rb3gen2-industrial-mezzanine] = " \
    qcom,qcs5430-iot-subtype9 \
    qcom,qcs6490-iot-subtype9 \
    "
FIT_DTB_COMPATIBLE[qcs6490-rb3gen2+qcs6490-rb3gen2-vision-mezzanine] = " \
    qcom,qcs5430-iot-subtype2 \
    qcom,qcs6490-iot-subtype2 \
    "
FIT_DTB_COMPATIBLE[qcs6490-rb3gen2+qcs6490-rb3gen2-vision-mezzanine-camx] = " \
    qcom,qcs6490-iot-camx \
    qcom,qcs6490-iot-subtype2-camx \
    "
```

这些条目在 FIT 镜像中生成一个 `configurations` 块,其中每个 `conf-N` 条目携带对应的 `compatible` 字符串和 `fdt` 列表。
UEFI 按顺序遍历这些配置,并选择第一个匹配的配置。

<Note>
  在 `configurations` 块中,更具体的 `compatible` 字符串必须出现在通用字符串之前。FIT 按顺序评估配置;第一个匹配的配置生效。有关 compatible 字符串标记的参考,请参阅[设备树架构](./device-tree-architecture#compatible-string-format)。
</Note>

## 用于 KVM 的 EL2 设备树

文件名中带有 `el2` 标记的设备树文件支持 Linux 在异常级别 2(EL2)运行以用于 KVM。构建系统将 `el2` 覆盖应用于平台 DTB,以生成 EL2 DTB 变体。目标平台默认启动进入 KVM 模式,少数尚未支持 KVM 的目标平台除外。请参阅发行说明了解平台能力。更多详情请参阅[启用虚拟化](./enable-virtualization)。

## Staging 设备树覆盖

文件名中带有 `staging` 标记的设备树文件用于启用存在于内核源码中但尚未提交到上游的内核树内驱动程序。示例包括 SoC 级 TGU 节点(`kodiak-staging.dtso`、
`lemans-staging.dtso`、`monaco-staging.dtso`、`talos-staging.dtso`)以及用于开发套件的板级 staging 以太网 PHY 覆盖。当 `VendorDtbOverlays` EFI 变量设置为 `staging` 时,构建系统会应用这些覆盖:

```bash theme={null}
echo -n "staging" > /tmp/overlay
efivar -n 882f8c2b-9646-435f-8de5-f208ff80c1bd-VendorDtbOverlays \
    -w -f /tmp/overlay
efivar -n 882f8c2b-9646-435f-8de5-f208ff80c1bd-VendorDtbOverlays -p
sync && reboot
```

<Note>
  当需要 staging 下游功能时,请使用 staging DTB。
</Note>

## CAMX 相机设备树覆盖

文件名中带有 `camx` 标记的设备树文件将上游相机子系统(`camss`)替换为 Qualcomm® CAMX 专有相机框架。板级 CAMX 覆盖(例如
`qcs6490-rb3gen2-vision-mezzanine-camx.dtso`、`lemans-evk-camx.dtso`、
`monaco-evk-camx.dtso`)会禁用上游 `camss` 节点并启用 CAMX 节点。当同时需要 CAMX 和 KVM 时,会应用组合的 `*-camx-el2.dtso` 覆盖。当 `VendorDtbOverlays` EFI 变量设置为 `camx` 时,构建系统会应用 CAMX 覆盖:

```bash theme={null}
echo -n "camx" > /tmp/overlay
efivar -n 882f8c2b-9646-435f-8de5-f208ff80c1bd-VendorDtbOverlays \
    -w -f /tmp/overlay
efivar -n 882f8c2b-9646-435f-8de5-f208ff80c1bd-VendorDtbOverlays -p
sync && reboot
```

<Note>
  仅在使用 Qualcomm 专有相机栈构建时才使用 CAMX DTB。在 CAMX 配置中,上游 `camss` 驱动程序已被禁用。
</Note>
