> ## 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.

# 使用 systemd-boot 和 UKI 配置并安全启动

systemd-boot 统一可扩展固件接口（UEFI）启动管理器提供了控制启动流程的选项，并加载用户选择的引导加载程序。配置文件、内核镜像、initrd 镜像和其他 EFI 镜像必须位于 EFI 分区上。

要将 Qualcomm Linux 内核直接作为 EFI 镜像运行，请使用 `CONFIG_EFI_STUB` 进行构建。systemd-boot 支持两种配置：

> * Type1：Type1 配置使用引导加载程序规范（BLS）描述文件。您可以在 EFI 上的 `/loader/entries/` 目录中找到这些文件。
> * Type2：Type2 配置使用统一内核镜像（UKI）。这些镜像将内核、initrd 和内核命令行组合到单个 EFI 可执行文件中。Type2 提供更好的安全性，因为 UKI 包含设备启动所需的全部信息。对 UKI 镜像签名可保护其中包含的所有实体。如果启用了 UEFI 安全启动，系统只会加载已签名的镜像，因此签名成为必需项。

有关更多详细信息，请参阅 [systemd-boot](https://www.freedesktop.org/software/systemd/man/latest/systemd-boot.html)。

**注意**

要使用启用了安全启动的设备，必须进行签名。

## **UKI**

UKI 是将 UEFI 启动 stub 程序、Qualcomm Linux 内核镜像、initrd 和其他资源组合到单个 UEFI 可移植可执行（PE）文件中的组合体。UEFI 启动 stub 在 UEFI PE 二进制文件内部查找内核调用所需的各种资源。这允许将各种资源组合到单个 UKI 镜像中，然后可以使用 sbsign 对其进行签名。Qualcomm Linux 使用 sbsign 对 PE 文件签名，而 DTB 等非 PE 文件则使用 OpenSSL 签名。

有关 UKI 的更多详细信息，请参阅 `unified_kernel_image`。下表显示了 `uki.efi` 的内容：

|      **uki.efi 文件的组件**      |                                                                                                       **内容**                                                                                                       |
| :-------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|    Initrd = Init ramdisk    |                                                                                  `initramfs-rootfs-image-rb3gen2-core-kit.cpio.gz`                                                                                 |
|         Linux = 内核镜像        |                                                                                          `Image`（因为 systemd-boot 需要未压缩的内核）                                                                                         |
|         Uname = 内核版本        |                                                                                                      `6.18.12`                                                                                                     |
|        Efi-arch = 架构        |                                                                                                       `aa64`                                                                                                       |
| Stub = System-boot efi stub |                                                                                                 `linuxx64.efi.stub`                                                                                                |
|    OS-release = 操作系统版本信息    | <ul><li>`ID = qcom-distro`</li><li>`Name = “Qualcomm Linux reference distribution”`</li><li>`VERSION = “2.0”`</li><li>`VERSION_ID = 2.0`</li><li>`PRETTY_NAME = “Qualcomm Linux reference distribution”`</li></ul> |

### **镜像 recipe**

`meta-qcom/recipes-kernel/images` 包含以下 recipe：

* `esp-qcom-image.bb` 生成 VFAT 镜像 `efi.bin`，其中包含 `uki.efi` 和 `systemd-boot`。

`meta-qcom/classes-recipe/image_types_qcom.bbclass` 类会调用 `esp-qcom-image`。

## **EFI 镜像**

EFI 镜像 `efi.bin` 是存储在闪存 EFI 分区中的 VFAT 文件系统镜像。此 VFAT 文件系统包含 UEFI 加载并将执行控制权转移给 systemd-boot 所需的镜像。为了将执行控制权转移给 systemd-boot 管理器，UEFI 会挂载 `efi.bin`，加载 `bootaa64.efi` 并执行它。systemd-boot 管理器解析 `loader.conf`，加载内核镜像，并将控制权转移给它。

有关 EFI 结构的更多信息，请参阅 [EFI 系统分区](https://wiki.archlinux.org/title/EFI_system_partition)。

以下是来自 Qualcomm Linux 的 `efi.bin` 示例结构。它在 `/ostree/poky-<sha256-sum>` 目录下包含 systemd-boot 的 `bootaa64.efi` 和 Qualcomm Linux 内核 `vmlinuz-<version>`。

<div className="flex flex-col items-center gap-2">
  <img src="https://mintcdn.com/qualcomm-prod/Im5W2pUR5LdqxAI6/Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/efi-bin-ostree.png?fit=max&auto=format&n=Im5W2pUR5LdqxAI6&q=85&s=1a1e3a52918f4ba4a2106344ead13f40" alt="图：生成的带 OSTree 支持的 ``efi.bin`` 文件" width="600" height="397" data-path="Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/efi-bin-ostree.png" />

  <p className="text-sm text-gray-700">
    图：生成的带 OSTree 支持的 `efi.bin` 文件
  </p>
</div>

## **签名**

安全启动是 UEFI 标准中的一项功能，但在 Qualcomm Linux 中默认未启用。启用后，安全启动会通过维护一个经过加密签名的二进制文件列表（这些文件在设备启动时经身份验证成功后才会运行），为预启动过程增加一层保护。这可确保设备的启动固件和 Linux 操作系统启动组件（例如启动管理器、内核和 initramfs）未被篡改。

UEFI 安全启动使用数字签名来验证其加载的二进制代码的真实性和完整性。UEFI 安全变量存储所有密钥。实现 UEFI 安全启动涉及使用平台密钥（PK）、密钥交换密钥（KEK）、数据库（DB）和禁用签名数据库（DBX）。

使用安全启动需要 PK、KEK 和 DB 密钥。允许存在多个 KEK、DB 和 DBX，但只允许一个 PK。

启用 UEFI 安全启动需要在系统中注册 PK。Qualcomm 建议在安全启动启用过程的最后一步配置 PK。有关 Qualcomm 如何实现 UEFI 安全启动功能的更多信息，请参阅[安全启动](https://dragonwingdocs.qualcomm.com/System/Security/security-features#secure-boot)。

### **用于为 Qualcomm Linux 构建生成的 Linux OS 镜像签名的主机工具** `signing_tool.py`

启用 UEFI 安全启动需要对 EFI 和 DTB 镜像签名。使用 `signing_tool.py` 主机签名工具可简化此过程。此命令行 Python 脚本在 Linux 主机（Ubuntu 20.04 或更高版本）上运行。它通过两次单独的操作自动完成 EFI 和 DTB 镜像的签名。

主机签名工具可在 [GitHub](https://github.com/quic/host-signing-tool) 上下载。

主机签名工具在安装了 Python3 的 Linux 计算机上运行。它可以在一次操作中签名 EFI 镜像或 DTB 镜像。要同时签名 EFI 和 DTB 镜像，您必须使用不同的输入调用该工具两次。

<div className="flex flex-col items-center gap-2">
  <img src="https://mintcdn.com/qualcomm-prod/Im5W2pUR5LdqxAI6/Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/host_tool_design_wbg.png?fit=max&auto=format&n=Im5W2pUR5LdqxAI6&q=85&s=7a9fca25853f012007d0fe97b5c9a7b5" alt="图：安装了 OpenSSL 和 sbsign 的 Linux 计算机" width="462" height="309" data-path="Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/host_tool_design_wbg.png" />

  <p className="text-sm text-gray-700">
    图：安装了 OpenSSL 和 sbsign 的 Linux 计算机
  </p>
</div>

主机工具需要未签名的 EFI 或 DTB 文件以及证书和密钥作为输入。调用后，该工具会解包未签名的镜像，使用提供的密钥和证书对可用项进行签名，然后重新打包镜像，用已签名版本替换未签名版本。

### **前提条件**

要运行此工具，请在 Linux 主机上安装以下内容：

* OpenSSL、sbsign 和 mtools 实用程序
* Python3
* pip、subprocess、shlex、socket、glob 和 shutil Python 模块

### **配置主机签名工具**

在开始操作之前，您必须先配置主机签名工具。

主机工具要求在 `config.ini` 配置文件中提供必要的信息。该工具读取此文件并相应地对镜像进行签名。以下代码片段显示了配置文件中的变量：

#### `config.ini` **文件**

```text theme={null}
[common]
# Section - 1: Common Selection
# Select operation: sign_image
operation = sign_image
# Possible values for file_path are 1. remote or 2. local
file_path = local
# If file_path == remote
local_machine_private_key_path = /usr2/<user_name_for_machine>/.ssh/id_rsa

# Section - 2: operation == sign_image related common selection
# Possible values for image_type are 1. efi or 2. dtb
image_type = efi
# This option is required if operation == sign_image & image_type == efi
loader_conf_timeout = 20

# Below options are required to fetch file from remote Linux machine in the same network (that is if file_path == remote)

# This option is useful if operation == sign_image & image_type == efi
[efi_config]
efi_remote_hostname = <remotemachine_ip_or_hostname_where_efi.bin_available>
efi_remote_username = <username_on_remote_machine_where_efi.bin_available>
efi_remote_filepath = <full_path_of_efi.bin_file_on_remotemachine>

# This option is useful if operation == sign_image. Both image_type requires this option
[keys_config]
keys_remote_hostname = <remotemachine_ip_or_hostname_where_keys_available>
keys_remote_username = <username_on_remote_machine_where_keys_available>
keys_remote_filepath = <full_path_of_keys_directory_on_remotemachine>

# This option is useful if operation == sign_image & image_type == dtb
[dtb_config]
dtb_remote_hostname = <remotemachine_ip_or_hostname_where_dtb_available>
dtb_remote_username = <username_on_remote_machine_where_dtb_available>
dtb_remote_filepath = <full_path_of_dtb_on_remotemachine>
```

表：config.ini 文件中的变量

|        **config.ini 中的变量**       |                     **取值**                    |                                                      **描述**                                                      |
| :------------------------------: | :-------------------------------------------: | :--------------------------------------------------------------------------------------------------------------: |
|            `operation`           |                  `sign_image`                 |                                                  使用此配置选择对镜像进行签名。                                                 |
|           `image_type`           |                   `efi/dtb`                   |                              如果 `operation == sign_image`，使用此配置选择分别签名 `efi` 或 `dtb`。                             |
|            `file_path`           |                 `local/remote`                | <ul><li>local：密钥和 efi.bin/dtb.bin 与脚本位于同一路径。</li><li>remote：从远程 Linux 计算机将 efi.bin/dtb.bin 和密钥复制到当前路径。</li></ul> |
| `local_machine_private_key_path` |    `<path of id_rsa file in localmachine>`    |                                   如果 `file_path =remote`，此文件用于与远程计算机建立 SSH 连接。                                   |
|       `loader_conf_timeout`      |             `<timeout in seconds>`            |                            systemd-boot 的等待时间，让您可以选择对二进制文件进行身份验证。签名 `efi.bin` 时需要此选项。                            |
|  `efi/keys/dtb_remote_hostname`  | `<ip or hostname of the remote Linuxmachine>` |                   如果 `file_path = remote`，主机工具会选择远程计算机的主机名，以便使用 SCP 从远程计算机复制 `efi/keys/dtb` 文件。                  |
|  `efi/keys/dtb_remote_username`  |         `<username_on_remote_machine>`        |          如果 `file_path = remote`，主机工具会选择远程计算机的用户名，以便使用 SCP 从远程计算机复制 `efi/keys/dtb` 文件，前提是该用户名已在远程计算机上创建。         |
|  `efi/keys/dtb_remote_filepath`  |    `<full_path_of_file_on_remote_machine>`    |                  如果 `file_path = remote`，主机工具会选择远程计算机上 `efi/key/dtb` 文件的路径，以便使用 SCP 从远程计算机复制该文件。                 |

要使用 `config.ini` 文件配置主机签名工具，请执行以下操作：

1. 设置 `operation` 变量以指定要执行的操作。选项为 `sign_image`。
2. 如果选择 `operation == sign_image`，请通过设置 `image_type` 变量指定要签名的镜像。选项为 `efi` 或 `dtb`。
3. 使用 `file_path` 变量指明未签名的 EFI 和 DTB 镜像、密钥和证书的位置。
   * 如果在配置文件中选择 `local`，请手动将 EFI 和 DTB 镜像、密钥和证书文件复制到本地工作目录：
     1. 在与脚本相同的路径下创建 `unsigned_binaries` 目录，然后将 `efi.bin` 和 `dtb.bin` 镜像复制到该目录中。
     2. 在与脚本相同的路径下创建 `keys` 目录，然后将 `db.auth`、`db.crt`、`db.key`、`KEK.auth` 和 `PK.auth` 文件复制到该目录中。
   * 如果希望脚本自动从同一网络中的远程 Linux 计算机复制所需文件，请在配置文件中选择 `remote`。在配置文件中，为以下变量提供信息：
     * `local_machine_private_key_path`（必填）
     * `[efi_config]` 部分（如果 `operation` 为 `sign_image` 且 `image_type` 为 `efi`）
     * `[keys_config]` 部分（如果 `operation` 为 `sign_image`）
     * `[dtb_config]` 部分（如果 `operation` 为 `sign_image` 且 `image_type` 为 `dtb`）**注意** 该脚本支持在同一网络内通过 SCP 从另一台 Linux 计算机复制文件。
4. 当配置文件中的 `image_type` 设置为 efi 时，请更新 `loader_conf_timeout` 变量。
5. 如果遗漏了任何配置信息，脚本在运行时会通过命令行提示您输入缺失的详细信息。

### **运行主机签名工具**

1. 完成代码构建过程并获得未签名的 `efi.bin` 和 `dtb.bin` 镜像后，运行主机签名工具。
2. 将主机签名工具文件（`signing_tool.py` 和 `config.ini`）存储在 Linux 计算机上。确保这两个文件位于同一工作目录中。
3. 按照配置说明设置主机签名工具。
4. 运行以下命令从命令行启动主机工具：`$python3 signing_tool.py`。主机签名工具会在屏幕上显示您的选择和操作命令。它还会在命令行中显示错误。工具完成处理后，会在同一工作目录中创建一个名为 `signed_binaries` 的目录。已签名的 `efi.bin` 或 `dtb.bin` 镜像存储在该目录中。签名完成后，该工具会删除其他用户创建的目录。
5. 请执行此过程两次，一次针对 `efi.bin`，一次针对 `dtb.bin`。每次签名操作后，在开始新操作之前，请删除 `signed_binaries` 目录。

### **主机签名工具工作流程**

下图显示了主机签名工具的工作流程：

<div className="flex flex-col items-center gap-2">
  <img src="https://mintcdn.com/qualcomm-prod/Im5W2pUR5LdqxAI6/Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/host_tool_workflow.png?fit=max&auto=format&n=Im5W2pUR5LdqxAI6&q=85&s=be77a37e353f6ab2ab555f83f8e86fbb" alt="图：主机签名工具工作流程" width="512" height="603" data-path="Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/host_tool_workflow.png" />

  <p className="text-sm text-gray-700">
    图：主机签名工具工作流程
  </p>
</div>

* 主机工具需要 `efi.bin` 和 `dtb.bin` 的路径（绝对路径或网络路径）。
  * 带 OSTree 支持的 `efi.bin` 包含 `vmlinuz-x.y.z`（Qualcomm Linux 内核镜像）和 `bootaa64.efi`（引导加载程序镜像）。
  * `dtb.bin` 包含 `qclinux_fit.img`。
* 主机工具需要 `certificate` 和 `key` 的路径（绝对路径或网络路径）来对镜像签名。
* 主机工具将 `efi.bin` 和 `dtb.bin` 挂载到 FAT 分区上，其目录结构如下所示，并各自遵循单独的签名流程：`efi.bin` 的目录结构：

  <div className="flex flex-col items-center gap-2">
    <img src="https://mintcdn.com/qualcomm-prod/Im5W2pUR5LdqxAI6/Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/1_efi_bin.png?fit=max&auto=format&n=Im5W2pUR5LdqxAI6&q=85&s=68418241b6ffa44c7083cc1ad92c2e65" alt="图：efi.bin" width="220" height="318" data-path="Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/1_efi_bin.png" />

    <p className="text-sm text-gray-700">
      图：efi.bin
    </p>
  </div>

  **图：efi.bin** 带 OSTree 支持的 `efi.bin` 的目录结构：

  <div className="flex flex-col items-center gap-2">
    <img src="https://mintcdn.com/qualcomm-prod/Im5W2pUR5LdqxAI6/Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/efi-bin-ostree.png?fit=max&auto=format&n=Im5W2pUR5LdqxAI6&q=85&s=1a1e3a52918f4ba4a2106344ead13f40" alt="图：带 OSTree 支持的 efi.bin" width="600" height="397" data-path="Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/efi-bin-ostree.png" />

    <p className="text-sm text-gray-700">
      图：带 OSTree 支持的 efi.bin
    </p>
  </div>

  **图：带 OSTree 支持的 efi.bin** `dtb.bin` 的目录结构：

  <div className="flex flex-col items-center gap-2">
    <img src="https://mintcdn.com/qualcomm-prod/Im5W2pUR5LdqxAI6/Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/1_multi_dtb_vfat.png?fit=max&auto=format&n=Im5W2pUR5LdqxAI6&q=85&s=ccb6c9e7f278f58e5f00d172628ac549" alt="图：dtb.bin" width="362" height="195" data-path="Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/1_multi_dtb_vfat.png" />

    <p className="text-sm text-gray-700">
      图：dtb.bin
    </p>
  </div>
* 对镜像签名后，主机工具会将 .auth 文件复制到 `efi.bin` 和 `dtb.bin` 的 `/loader/keys/authkeys` 目录中。
* 主机工具在 `systemd-boot` 加载程序配置中配置等待时间。此等待时间会暂停内核加载，让您可以查看并选择 `systemd-boot` 菜单选项。`loader.conf` 文件必须存在于更新后的 `efi.bin` 文件中。**注意**
  此签名过程不适用于 `dtb.bin` 文件。
  * 主机工具会配置 `/loader/loader.conf`。
  * `loader.conf` 的语法为 `timeout x`，其中 x = 超时时间（秒）。
* 镜像签名后，主机工具会将 `efi.bin/dtb.bin` 从 FAT 分区卸载。将已签名的 `efi.bin` 和 `dtb.bin` 存储在主机上与主机工具类似的路径下的 `signed_binaries` 目录中。
* 以下是已签名的 `efi.bin` 和 `dtb.bin` 的目录结构：

  <div className="flex flex-col items-center gap-2">
    <img src="https://mintcdn.com/qualcomm-prod/T1k4QQ7G3l_dE-rX/Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/signed_efi-bin_and_dtb-bin.png?fit=max&auto=format&n=T1k4QQ7G3l_dE-rX&q=85&s=32b34574314131cb3c1e6b53e8914f0a" alt="图：efi.bin 和 dtb.bin 文件的目录结构" width="968" height="673" data-path="Key-Documents/Yocto-Guide/media/k2c-qli-yocto-build-ga/signed_efi-bin_and_dtb-bin.png" />

    <p className="text-sm text-gray-700">
      图：efi.bin 和 dtb.bin 文件的目录结构
    </p>
  </div>

### `efi.bin` **签名流程**

* 主机工具使用 `sbsign` 实用程序分别对 `uki.efi` 或 vmlinuz.x.y.z 和 `bootaa64.efi` 镜像进行签名。
* `sbsign` 的签名过程需要 `certificate` 和 `key`。请核对以下语法，其中 `dsk1.key` 为密钥，`dsk1.crt` 为证书，输出文件名与输入文件相同：
  ```text theme={null}
  sbsign --key <key file> --cert <cert file> <efi file> <output file name>
  ```
  **示例：**
  ```text theme={null}
  sbsign –key dsk1.key –cert dsk1.crt bootaa64.efi bootaa64.efi
  ```
  ```text theme={null}
  sbsign --key dsk1.key --cert dsk1.crt uki.efi uki.efi
  ```
  ```text theme={null}
  sbsign --key dsk1.key --cert dsk1.crt vmlinuz.x.y.z vmlinuz.x.y.z
  ```

### `dtb.bin` **签名流程**

* 主机工具需要 `dtb.bin` 文件的路径。
* 主机工具需要 `key` 和 `certificate` 的路径（绝对路径或网络路径）来对镜像签名。
* UEFI 安全启动需要 PE 格式的文件进行验证。`dtb` 等非 PE 文件无法使用 `sbsign` 签名，因为此签名工具要求输入 PE 格式的文件。
* 主机工具使用 `openssl` 实用程序对 `dtb` 文件签名。请核对以下语法，其中 `dsk1.key` 为密钥，`dsk1.crt` 为证书：
  ```text theme={null}
     openssl cms -sign -inkey <.key file> -signer <.crt file> -binary -in <img file> --out <output .sig file> -outform DER
  ```
  **示例：**
  ```text theme={null}
     openssl cms -sign -inkey dsk1.key -signer dsk1.crt -binary -in <foo.img file> --out <foo.sig file > -outform DER
  ```
  此命令将 DTB 文件的签名添加到一个单独的文件（`foo.sig`）中，不会修改原始文件（`foo.img`）。因此，主机工具必须同时保留这两个文件，其中 `*.sig` 文件在 UEFI 安全启动验证期间使用。

## **多 DTB 支持**

Qualcomm 支持基于相同硬件 SoC 的多个 Qualcomm 开发套件。例如，QCS6490 开发套件变体包括 RB3 Gen 2 Core 开发套件和 RB3 Gen 2 Vision 开发套件。

每个 Qualcomm 开发套件变体在内核中都有自己的 DTB。在启动期间，UEFI 会根据具体的 Qualcomm 开发套件变体选择合适的 DTB。为此，请按如下方式使用多 DTB 扁平镜像树（FIT）镜像：

### **生成多 DTB FIT 镜像**

对于单个硬件 SoC 需要多个 DTB 的平台，Qualcomm Linux 支持生成基于 FIT 的多 DTB 镜像。这使 UEFI 能够在启动时根据检测到的硬件变体选择合适的 DTB。

对于支持 FIT 镜像的平台，多个 DTB 通过机器配置文件中的 `KERNEL_DEVICETREE` 变量列出。例如，以下来自 `meta-qcom/conf/machine/rb3gen2-core-kit.conf` 的代码片段为 RB3 Gen 2 Core 开发套件定义了两个 DTB：

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

这些 DTB 会在构建过程中合并为单个 FIT 镜像。

> 1. 添加 DTB compatible 字符串：FIT 镜像中包含的每个 DTB 都必须有一个关联的 compatible 字符串。UEFI 在启动时使用这些 compatible 字符串选择正确的 DTB。
>    * compatible 字符串在 `meta-qcom/conf/machine/include/fit-dtb-compatible.inc` 中定义。
>    * 这些值必须参考以下位置提供的 DTB 元数据来推导：[https://github.com/qualcomm-linux/qcom-dtb-metadata](https://github.com/qualcomm-linux/qcom-dtb-metadata) 对于 RB3 Gen 2 Core Kit 示例，请添加以下条目：

```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 \
 "
```

2. 启用多 DTB 打包：要将生成的 FIT 镜像打包为 VFAT 镜像（`dtb.bin`），请在 `meta-qcom/classes-recipe/image_types_qcom.bbclass` 中设置以下变量：
   ```text theme={null}
   QCOM_DTB_DEFAULT ?= "multi-dtb"
   ```
   当此变量设置为 multi-dtb 时，构建系统会将包含 `KERNEL_DEVICETREE` 中列出的所有 DTB 的合并 FIT 镜像打包到 `dtb.bin` 中。

#### **不支持 FIT 镜像的开发套件**

某些平台不支持基于 FIT 的 DTB 选择。这包括某些 ride 开发套件，例如：

* `qcs9100-ride-sx`
* `qcs8300-ride-sx`

对于这些套件，只能将单个 DTB 打包到 `dtb.bin` 中。例如，以下来自 `meta-qcom/conf/machine/qcs9100-ride-sx.conf` 的代码片段列出了多个 DTB：

```text theme={null}
KERNEL_DEVICETREE ?= " \
                     qcom/qcs9100-ride.dtb \
                     qcom/qcs9100-ride-r3.dtb \
                     qcom/sa8775p-ride.dtb \
                     qcom/sa8775p-ride-r3.dtb \
                     "
```

由于此套件不支持基于 FIT 的 DTB 选择，必须选择单个 DTB 作为默认值。请在同一机器配置文件中按如下方式设置 `QCOM_DTB_DEFAULT` 变量：

```text theme={null}
QCOM_DTB_DEFAULT ?= "qcs9100-ride-r3"
```

采用此设置后，只有 `qcs9100-ride-r3.dtb` 会被打包到 VFAT 镜像（`dtb.bin`）中并在启动期间使用。

### **DTB 分区**

* 生成的名为 `dtb.bin` 的 VFAT 镜像包含合并后的 DTB 镜像。Qualcomm 开发套件上有一个名为 `dtb` 的专用分区。请将 `dtb.bin` 烧录到此分区。
* UEFI 会解析 `dtb` 分区中存在的合并 DTB，并为硬件选择匹配的 DTB。

## **后续步骤**

* 有关 UEFI 安全启动实现的更多信息，请参阅[安全启动](https://dragonwingdocs.qualcomm.com/System/Security/security-features#secure-boot)。
* 有关 UEFI 变量管理，请参阅[使用 efivar 工具管理 UEFI 环境变量](./manage-uefi-environment-variables-using-the-efivar-tool)。
* 有关使用 capsule 的 OTA 固件更新，请参阅[使用 capsule 和 OSTree 机制更新 Qualcomm Linux 上的固件和操作系统](./update-firmware-and-os-on-qualcomm-linux-using-capsule-and-os-tree-mechanisms)。
