
图: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-<DISTRO>/tmp-glibc/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 发行版功能。

