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

# 处理胶囊

设备上的固件通过 UEFI 使用胶囊进行更新。此过程涉及将固件更新负载捕获到胶囊 \[.cap 文件] 中，然后由系统固件处理该胶囊以更新设备固件。

<Note>
  本文档中提到的 base 和 advanced 变体仅适用于 QLI 1.x。对于 QLI 2.x，不存在变体之分，默认变体等同于 QLI 1.x 中的 advanced 变体。
</Note>

## **胶囊更新中使用的 UEFI 变量**

与平台固件交互的协议和服务实现了操作系统与 UEFI 之间的通信。UEFI 提供标准启动环境、包含平台信息的数据表，以及供 OS 加载程序和 OS 使用的启动/运行时服务调用。

<Frame caption="**表：胶囊更新中使用的 UEFI 变量**" />

| 变量名称                                        | 说明                                                                                                                                                                                                                                                                                                                                        |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **OsIndications**                           | 此变量由操作系统拥有，用于指示操作系统希望固件启用的功能或希望固件执行的操作。操作系统设置该变量，UEFI 清除它。                                                                                                                                                                                                                                                                                |
| **OsIndicationsSupported**                  | 此变量由固件拥有，指示固件支持哪些操作系统指示功能和操作。                                                                                                                                                                                                                                                                                                             |
| **OsTrialBootStatus**<br />*(32 位 UEFI 变量)* | **位图：**<br /><br />• **7:0 – Version**：`OsTrialBootStatus` 的版本号<br />• **11:8 – TrialBootMaxCount**：由操作系统在触发胶囊更新之前设置<br />• **15:12 – TrialBootCount**：由 UEFI 设置或递增（如果操作系统未清除 `TrialBootEnabled`）。操作系统可以将其设置为 `TrialBootMaxCount` 以触发固件回滚<br />• **16 – TrialBootEnabled**：胶囊更新后由 UEFI 设置为 `1`，并在 OTA 更新成功后由操作系统清除<br />• **31:17 – 未使用** |
| **EFI 系统资源表 (ESRT)**                        | ESRT 表在胶囊更新后由 UEFI 设置。                                                                                                                                                                                                                                                                                                                    |

有关 OsIndications 和 OsIndicationsSupported 变量的更多信息，请参阅 [Exchanging information between the OS and Firmware](https://uefi.org/specs/UEFI/2.10/08_Services_Runtime_Services.html?highlight=osindications#exchanging-information-between-the-os-and-firmware)。

<Note>
  * 如果 ESP 分区中（在 EFI/UpdateCapsule 中）有多个胶囊，则将所有胶囊纳入更新范围，并按字母顺序进行更新。
  * 将所有 UEFI 非易失性变量存储在回滚保护内存块 (RPMB) 分区中，该分区必须处于已配置（Provisioned）状态。
    * 在启用了 Qualcomm 安全启动的设备上自动配置 RPMB。
    * 在 Qualcomm 非安全设备上，不要自动配置 RPMB；而是使用测试密钥进行配置。
    * 如果您在非安全设备上使用测试密钥配置了 RPMB，则在设备上启用 Qualcomm 安全启动时无法使用设备密钥重新配置它。
    * 使用 `rpmbClient` 应用程序从 Linux 进行 RPMB 配置。有关更多信息，请参阅 [Qualcomm Security Linux Guide](https://dragonwingdocs.qualcomm.com/System/Security/verify-the-security-configurations-of-qualcomm-linux)。
</Note>

## **用于胶囊更新状态的 EFI 系统资源表 (ESRT)**

ESRT 是一种可选机制，用于标识提供固件更新所使用的设备和系统固件资源。每个 ESRT 条目描述一个可更新的固件资源，并报告上次尝试更新的状态。下表列出了用于报告上次尝试更新状态的 ESRT 条目：

<Frame caption="**表：ESRT 条目**" />

| **ESRT 字段**              | **说明**                                                           |
| ------------------------ | ---------------------------------------------------------------- |
| FwClass                  | 包含一个 GUID，用于标识要通过 *UpdateCapsule()* 更新的固件组件。                     |
| FwType                   | 标识固件资源的类型。                                                       |
| FwVersion                | 表示固件资源的当前版本。该值必须始终递增，因为较大的数字表示较新的版本。                             |
| LowestSupportedFwVersion | 指定系统或设备可以回滚到的最低固件资源版本。                                           |
| CapsuleFlags             | 包含在胶囊头中设置的 *EFI\_CAPSULE\_HEADER* 中定义的 *CapsuleGuid* 标志（位 0-15）。 |
| LastAttemptVersion       | 指示系统上次尝试更新的固件版本（使用与固件版本相同的格式）。                                   |
| LastAttemptStatus        | 描述该固件资源条目上次固件更新尝试的结果。                                            |

操作系统通过 sysfs 路径公开 ESRT 内容。

```text theme={null}
/sys/firmware/efi/esrt/entries/entry0/
sh-5.1# cd /sys/firmware/efi/esrt/entries/entry0/
sh-5.1# ls
capsule_flags  fw_type     last_attempt_status   lowest_supported_fw_version
w_class       fw_version  last_attempt_version
```

UEFI 在胶囊更新后设置 ESRT 表。X 表示胶囊更新之前的固件版本。Y 是胶囊 \[.cap] 文件中提供的固件版本。

<Note>
  只有在 RPMB 已配置的情况下，上次尝试的固件版本才可用。
</Note>

| **上次尝试的固件版本** | **当前固件版本** | **last\_attempt\_status** | **胶囊更新场景** |
| ------------- | ---------- | ------------------------- | ---------- |
| Y             | Y          | 0                         | 更新成功       |
| Y             | X          | 1                         | 胶囊更新失败     |
| 0             | X          | 0                         | 胶囊元数据失败    |
| Y             | X          | 0                         | 固件回滚完成     |

有关 ESRT 的更多信息，请参阅 [Firmware Update and Reporting - UEFI Specification 2.10 documentation](https://uefi.org/specs/UEFI/2.10/23_Firmware_Update_and_Reporting.html#efi-system-resource-table)。

## **使用胶囊进行固件更新**

该流程图展示了如何使用 UEFI 胶囊方法更新设备固件，利用不同的 UEFI 变量并支持回滚。

<div style={{ textAlign: 'center', width: '100%' }}>
  <img src="https://mintcdn.com/qualcomm-staging/uWQLnBcS9sxlZhgB/System/Boot/media/k2c-qli-boot/capsule-flowchart.svg?fit=max&auto=format&n=uWQLnBcS9sxlZhgB&q=85&s=7dff4b3d028807b1724a8cb52ee5cf71" alt="胶囊流程图" style={{ display: 'block', margin: '0 auto' }} width="879" height="1014" data-path="System/Boot/media/k2c-qli-boot/capsule-flowchart.svg" />
</div>

1. **启动**：空中下载 (OTA) 更新过程开始，操作系统准备更新胶囊，向 UEFI 发出信号（通过设置 `OsIndications`）以开始更新。操作系统设置 `TrialBootMaxCount` 以跟踪允许的试启动次数，然后重启设备。
2. **UEFI 更新**：重启后，系统检查 `OsIndications`。如果存在，则执行胶囊更新，更新 EFI 系统资源表 (ESRT)，清除 `OsIndications`，并且如果设置了 `TrialBootMaxCount`，则启用 `TrialBootEnabled` 并再次重启系统。
3. **试启动处理**：
   * 如果未设置 `OsIndications`，系统会检查 `TrialBootEnabled` 是否处于活动状态。
   * 如果 `TrialBootEnabled` 处于活动状态且 `TrialBootCount` 等于 `TrialBootMaxCount`，则检查回滚计数。
     * 如果允许回滚，UEFI 将还原固件，更新 ESRT 并重启。
     * 如果不允许回滚，则表示已达到回滚限制。
   * 如果 `TrialBootCount` 小于 `TrialBootMaxCount`，则递增 `TrialBootCount` 并继续该过程。
4. **完成**：系统启动到操作系统，检查 ESRT，如果操作系统成功启动，则重置 `TrialBootEnabled` 字段。
5. **结果**：
   * 如果 `TrialBootEnabled` 未处于活动状态，则确认 OTA 更新已完成。
   * 系统清除 `OtaTrialBootStatus` 并将 `LwSupportedFwVersion` 设置为当前固件版本以禁用回滚。
6. **恢复**：如果在更新过程中固件胶囊更新失败，UEFI 具有恢复机制以保持稳定性和功能性。
   1. **回滚**：如果允许回滚，UEFI 将恢复到之前的固件版本，并将固件还原到更新尝试之前的状态。
   2. **ESRT 更新**：系统更新 ESRT 以反映回滚。
   3. **重启**：回滚完成后，UEFI 触发重启，以确保运行的是之前的稳定固件版本。此过程应用更新，并在试用期间出现问题时启用回滚。

身份验证对于在固件更新期间保持安全性和稳定性至关重要。它有助于实现以下目标：

* 确保系统仅应用来自可信来源的更新。
* 防止恶意或未经授权的更新。
* 验证数字签名以确认传输期间的完整性。
* 仅安装经过验证和测试的更新。
* 降低因固件故障导致系统崩溃或故障的风险。
