
图:Qualcomm Linux 的 OTA 更新
使用 capsule 更新固件
Capsule 更新是一种在启用了 Qualcomm Linux 的设备上更新固件的方法。UEFI capsule 将固件打包成二进制格式。当设备启动并在正常任务模式下运行时,它会下载 capsule 并将其部署到 EFI 分区。重启后,在下一个启动周期中,UEFI 会处理该 capsule 并将更新应用到设备固件。用于 Linux 操作系统更新的 OSTree
OSTree 是一个用于管理基于 Linux 的操作系统的版本控制、原子更新的工具。它的工作方式类似于整个 Linux 文件系统的 git 仓库。OSTree 将文件系统树的快照存储在仓库中,设备通过网络拉取这些快照。借助 OSTree,更新是原子性的并支持回滚,因此更新中断不会破坏系统。IoT 和边缘设备可以从安全、一致的更新中受益,在出现问题时可以回滚。结合使用 capsule 和 OSTree 实现完整的 OTA 软件更新
要在单个 OTA 系统中管理固件和操作系统更新,请结合使用 capsule 和 OSTree 更新机制。capsule 更新机制首先处理固件更新,更新底层固件。capsule 更新完成后,系统重启并进入 Linux 操作系统,在那里检查并应用 OSTree 更新。Qualcomm Linux 使用 capsule 通过 UEFI 更新底层固件。 系统按照以下流程使用 capsule 更新固件:- 一个称为 UEFI capsule 的二进制文件封装了固件更新。
- 系统通过将 capsule 二进制文件存储在挂载的
/EFI路径中,将其传递给 UEFI。 - UEFI 固件在启动周期中处理该 capsule,并将更新应用到设备固件。

图:OTA 更新期间的存储概览
- Linux 操作系统镜像
efi.bin文件包含 UKI、initrd 和引导加载程序配置文件。OSTree 在部署期间创建一个新的配置文件。它列出了复制到 EFI 分区的新内核和 initramfs 镜像的路径。system.img文件包含 rootfs,包括/ostree、/ostree/repo和/ostree/deploy等关键组件。创建新部署时,OSTree 会更新文件系统树以反映操作系统的新版本。- 固件镜像 有关固件镜像列表的信息,请参阅 GitHub。
更新 capsule 和 HLOS
下图显示了 capsule 和高级操作系统(HLOS)更新流程:
图:Capsule 和 HLOS 更新流程
- 将
<capsule>.capcapsule 文件复制到 EFI 分区,该分区在已启动的设备上挂载于/boot/EFI/UpdateCapsule。 - 使用
EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED设置 EFI 变量(efivar)OsIndications标志并重启设备。当 UEFI 通过OsIndications标志检测到 capsule 更新请求时,会执行以下步骤:- UEFI 从
OsIndications标志识别出有可用于更新的 capsule。 - UEFI 对 capsule 进行身份验证,并从 capsule 中更新固件镜像。
- capsule 更新的状态会更新到 EFI 系统资源表(ESRT)中。
- 如果 capsule 更新期间出现故障,UEFI 会将固件回滚到先前的版本。UEFI 成功从 capsule 更新固件后,设备将使用新固件启动。
- UEFI 从
- 将 OSTree 仓库复制到设备上。使用 OSTree 命令为 HLOS 更新创建新部署,此时会创建一个带有计数标签的新配置文件,然后重启设备。
- Systemd-boot 选取新的配置文件并启动内核和用户空间。设备使用更新后的固件和 HLOS 软件启动。
systemd-bless-boot.service将新配置标记为良好。 - 重置
OtaStatusefivar中的TrialBootEnabled标志,以指示固件正常。UEFI 会检查此 efivar 以提交新固件。
使用 capsule 更新固件
下图显示了固件更新流程:
图:使用 capsule 更新固件
注意
有关 firmware_capsule.cap capsule 生成的更多信息,请参阅 UEFI 中的 capsule 生成。
- 要在设备上创建
UpdateCapsule文件夹,请运行以下命令: - 将 capsule 复制到设备上:
- 在设备上创建包含指定十六进制数据的
data.hex文件: - 使用
efivar工具将设备上data.hex的内容写入 UEFI 变量OsIndications:有关 UEFI 变量的更多信息,请参阅更新与恢复。 - 使用
efivar工具打印OsIndicationsUEFI 变量的值: - 重启设备:
- 检查 ESRT 表条目:
- 检查
last_attempt_status命令的输出。如果为 0,则更新成功: - 检查
last_attempt_version命令的输出: - 检查
fw_version命令的输出。如果last_attempt_version和fw_version相同,则更新成功:
- 检查
使用 OSTree 更新 Linux 操作系统
下图显示了 Linux 操作系统更新流程:
图:使用 OSTree 更新 Linux 操作系统
- 要检查 Qualcomm 设备中的当前部署,请运行以下命令:
输出:
*表示设备当前启动所使用的部署。 ostree_repo软件包位于主机开发计算机上的<workspace>/build/tmp/deploy/images/<MACHINE>/路径中。例如,<workspace>/build/tmp/deploy/images/rb3gen2-core-kit/。使用以下scp命令将ostree_repo软件包从主机计算机复制到 Qualcomm 设备:- 在 Qualcomm 设备上拉取本地 OSTree 仓库。
要查找该命令所需的
branch_name,请运行以下命令:输出:在上述输出中,rb3gen2-core-kit是一个示例分支名称。 - 在 Qualcomm 设备上创建部署:
这会在
/boot/loader/entries/目录中创建ostree-2-poky.conf配置文件。有关更多信息,请参阅 Systemd 启动计数 - 成功启动。 - 重启设备:
- 检查设备是否使用所创建的部署启动:
输出:要在构建主机计算机上验证新创建的部署,请检查
<workspace>/build/tmp/work/<MACHINE>/<IMAGE>/ota-sysroot/ostree/deploy/poky/deploy路径中的部署。例如,<workspace>/build/tmp/work/rb3gen2-core-kit/qcom-multimedia-image/ota-sysroot/ostree/deploy/poky/deploy。
Systemd-boot 计数 - 成功启动
下图显示了成功启动时的 systemd-boot 计数流程:
图:成功启动时的 Systemd-boot 计数
- 当 OSTree 部署新配置时,它会创建一个名称中带有
+3标签的配置文件,表示最大重试次数。这启用了启动计数。 - systemd-boot 检测到条目文件名中的
+3标签,并将其重命名为ostree-conf+2-1.conf,表示已开始一次启动尝试。重命名文件后,启动过程继续。 systemd-bless-boot-generator创建systemd-bless-boot.service,该服务被设置为在到达boot-complete.target时启动。systemd-bless-boot.service通过移除计数器标签+2-1并将文件重命名为ostree-conf.conf,将新配置标记为成功。
Systemd 启动计数 - 启动失败与回滚
下图显示了启动失败和回滚时的 systemd-boot 计数流程:
图:启动失败和回滚时的 Systemd-boot 计数
- 当 OSTree 部署新配置时,它会创建一个名称中带有
+3标签的 systemd 配置文件,表示最大重试次数,例如ostree-boot+3.conf。这启用了启动计数。 - systemd-boot 检测到配置文件名中的
+3标签,并将其重命名为ostree-boot+2-1.conf,表示已开始一次启动尝试。重命名文件后,启动过程继续。 systemd-bless-boot-generator创建systemd-bless-boot.service,该服务在到达boot-complete.target时启动。如果 Linux 启动过程中出现任何故障,systemd-bless-boot.service不会从配置文件中移除+2-1计数器标签。- 在随后的启动中,systemd-boot 检测到配置文件名中的
+2-1标签,将文件重命名为ostree-boot+1-2.conf,并尝试使用它启动。 - 如果第二次尝试时 Linux 启动失败,
systemd-bless-boot.service不会从配置文件中移除计数器标签+1-2。 - 在下次启动时,systemd-boot 检测到配置文件名中的
+1-2标签,将文件重命名为ostree-boot+0-3.conf,并尝试使用它启动。这是启动 Linux 部署的最后一次尝试。 - 如果设备在第三次尝试中未能启动 Linux,
systemd-bless-boot.service不会从配置文件中移除计数器标签+0-3。 - 在随后的启动中,systemd-boot 发现配置文件名中的
+0-3标签。由于计数器已归零,该条目(配置文件)被视为无效。systemd-boot 通过尝试有效的配置文件条目回退到早期版本。
Usrmerge
Linux 中的 Usrmerge 功能通过将某些目录合并到/usr 路径下来简化文件系统布局。它分别将 /bin、/sbin 和 /lib 与 /usr/bin、/usr/sbin 和 /usr/lib 合并。
启用 Usrmerge 后,/bin、/sbin 和 /lib 中的可执行文件和库分别放置在 /usr/bin、/usr/sbin 和 /usr/lib 中。原始目录成为指向其 /usr 对应目录的符号链接。这种统一的结构使维护更容易并减少冗余,因为二进制文件和库只有一个位置,而不是根级目录和 /usr 目录的单独位置。符号链接确保了兼容性,使引用 /bin 等路径的脚本和软件能够继续运行。
Linux 发行版正在采用 Usrmerge,以符合文件系统层次结构标准(FHS)建议,并简化根文件系统,特别是在容器化和嵌入式系统中。
Debian、Ubuntu 和 Fedora 等发行版已将 Usrmerge 作为其系统布局的一部分,使其成为最新版本中的标准。过渡过程包括创建符号链接,并将原始目录中剩余的文件移动到其 /usr 对应位置。
在 Qualcomm Linux 中管理 /var、/home、/media、/mnt、/opt、/srv 和 /usr
OSTree 将 /var 视为持久目录。这意味着用户和运行时在 /var 下创建的内容不会被 OSTree 触及,并在 OTA 更新之间保持不变。有关更多信息,请参阅 OSTree 概述。
在 OTA 更新期间不被 OSTree 触及的其他目录包括 /home、/media、/mnt、/opt 和 /srv。OSTree 将这些目录映射为符号链接,如下所示:
/home是指向/var/rootdirs/home的符号链接/media是指向/var/rootdirs/media的符号链接/mnt是指向/var/rootdirs/mnt的符号链接/opt是指向/var/rootdirs/opt的符号链接/srv是指向/var/rootdirs/srv的符号链接
/home、/media、/mnt、/opt、/srv 和 /var 下的任何运行时数据在 OTA 更新之间保持持久。
为了保持文件系统的干净和一致,请勿在构建时在上述目录下安装任何产物。在构建时安装在这些目录中的任何产物都不会被打包到由 Qualcomm Linux 构建命令(即 bitbake <image recipe>)生成的 rootfs 镜像中。
要处理持久路径下文件和目录的运行时创建,请执行以下操作:
进程在需要时于运行时创建这些文件或目录。
OSTree 在
/run/、/var/lib/、/var/cache/和/var/log/下的路径可以由相应的 systemd 单元文件创建。这里有一个参考。- 使用 systemd-tmpfiles 在启动时创建文件、符号链接和目录。
/usr 处创建只读绑定挂载,确保核心操作系统文件对用户保持不可变。这种方法有助于维护系统完整性和安全性。OSTree 使用 /usr 挂载点部署下一次更新。
注意在启用了 OSTree 的 Qualcomm Linux 中,
- OSTree 允许在构建时在
/var/local路径下安装文件和目录。- 尽管 OSTree 会保留构建时安装在
/usr下的内容,但它不会将安装在/usr/local子目录下的内容打包到 rootfs 镜像中。
/etc 目录的管理方式既支持系统更新,也支持本地定制。
/etc目录是可变的,允许在运行时进行修改,以维护需要在更新之间持久保留的系统配置。- OSTree 支持将
/usr/etc目录中的配置文件合并到/etc。这使 OSTree 能够更新默认配置,同时保留所做的任何本地更改。- 应用更新时,OSTree 会使用文件的原始版本、新更新中的文件版本以及本地修改的文件版本,对
/etc中的配置文件执行三方合并。- 如果合并过程中出现冲突,OSTree 会保留运行时的修改。这有助于保持系统稳定性,并确保关键配置不会被覆盖。
SOTA 发行版特性
软件空中下载(SOTA)发行版特性允许对嵌入式系统和 IoT 设备进行远程更新。它集成了 OSTree 等系统更新工具,使设备无需物理接触即可接收和安装更新。 要在 Qualcomm Linux 中启用 SOTA 发行版特性,请运行以下构建命令:此命令会自动为您的构建配置并启用 SOTA 发行版特性。

