Skip to main content
空中下载(OTA)更新对于保持设备正常运行至关重要,尤其是嵌入式系统和 IoT 设备。这些更新使设备能够接收并安装更新。 Qualcomm Linux 使用 capsule 更新机制来更新固件镜像,并使用 OSTree 更新机制来更新 Linux 操作系统。
图:Qualcomm Linux 的 OTA 更新

图: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 更新固件:
  1. 一个称为 UEFI capsule 的二进制文件封装固件更新。
  2. 系统通过将 capsule 二进制文件存储在挂载的 /EFI 路径中,将其交付给 UEFI。
  3. UEFI 固件在启动周期中处理该 capsule,并将更新应用到设备固件。
Qualcomm Linux 使用 OSTree 管理 Linux 操作系统。系统将 Qualcomm Linux 构建生成的更新包复制到设备上,并使用使用 OSTree 的 Linux 操作系统更新流程中列出的命令将其暂存以待激活。设备重启后,将应用该更新包。 下图显示了使用 OSTree 的 Linux 操作系统的存储视图。 运行时(Runtime)视图指示默认部署时存储中的哪些目录在运行时被映射到挂载点。 创建新部署后的存储视图显示当设备成功创建新的 OSTree 部署时闪存存储如何更新。此部署是新创建的,并将在下次重启时尝试作为新的 Linux 操作系统。
图:OTA 更新期间的存储概览

图:OTA 更新期间的存储概览

以下是作为 OTA 一部分更新的 Linux 操作系统和固件镜像列表:
  • 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 和 HLOS 更新流程

要更新 capsule 和 HLOS,请执行以下操作:
  1. <capsule>.cap capsule 文件复制到 EFI 分区,该分区在已启动的设备上挂载于 /boot/EFI/UpdateCapsule
  2. 使用 EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED 设置 EFI 变量(efivar)OsIndications 标志并重启设备。当 UEFI 通过 OsIndications 标志检测到 capsule 更新请求时,将执行以下步骤:
    1. UEFI 通过 OsIndications 标志识别出有可用于更新的 capsule。
    2. UEFI 对 capsule 进行身份验证,并从 capsule 更新固件镜像。
    3. Capsule 更新的状态会在 EFI 系统资源表(ESRT)中更新。
    4. 如果在 capsule 更新期间出现故障,UEFI 会将固件回滚到之前的版本。UEFI 成功从 capsule 更新固件后,设备将使用新固件启动。
  3. 将 OSTree 仓库复制到设备。使用 OSTree 命令为 HLOS 更新创建新部署,会创建一个带有计数标签的新配置文件,然后重启设备。
  4. Systemd-boot 选取新的配置文件并启动内核和用户空间。设备使用更新后的固件和 HLOS 软件启动。systemd-bless-boot.service 将新配置标记为良好。
  5. 重置 OtaStatus efivar 中的 TrialBootEnabled 标志,以表明固件良好。UEFI 检查此 efivar 以提交新固件。

使用 capsule 更新固件

下图显示了固件更新流程:
图:使用 capsule 更新固件

图:使用 capsule 更新固件

要使用 capsule 更新固件,请执行以下操作:
注意 有关 firmware_capsule.cap capsule 生成的更多信息,请参阅 UEFI 中的 capsule 生成
  1. 要在设备上创建 UpdateCapsule 文件夹,运行以下命令:
  2. 将 capsule 复制到设备:
  3. 在设备上创建包含指定十六进制数据的 data.hex 文件:
  4. 使用 efivar 工具将设备上 data.hex 的内容写入 UEFI 变量 OsIndications
    有关 UEFI 变量的更多信息,请参阅更新和恢复
  5. 使用 efivar 工具打印 OsIndications UEFI 变量的值:
  6. 重启设备:
  7. 检查 ESRT 表条目:
    1. 检查 last_attempt_status 命令的输出。如果为 0,则更新成功:
    2. 检查 last_attempt_version 命令的输出:
    3. 检查 fw_version 命令的输出。如果 last_attempt_versionfw_version 相同,则更新成功:

使用 OSTree 更新 Linux 操作系统

下图显示了 Linux 操作系统的更新流程:
图:使用 OSTree 更新 Linux 操作系统

图:使用 OSTree 更新 Linux 操作系统

要使用 OSTree 更新 Linux 操作系统,请执行以下操作:
  1. 要检查 Qualcomm 设备中的当前部署,运行以下命令:
    输出:
    * 表示设备当前启动所使用的部署。
  2. ostree_repo 软件包位于主机开发计算机上的 <workspace>/build/tmp/deploy/images/<MACHINE>/ 路径中。例如 <workspace>/build/tmp/deploy/images/rb3gen2-core-kit/。使用以下 scp 命令将 ostree_repo 软件包从主机复制到 Qualcomm 设备:
  3. 在 Qualcomm 设备上拉取本地 OSTree 仓库。
    要查找该命令所需的 branch_name,运行以下命令:
    输出:
    在上述输出中,rb3gen2-core-kit 是一个示例分支名称。
  4. 在 Qualcomm 设备上创建部署:
    这会在 /boot/loader/entries/ 目录中创建 ostree-2-poky.conf 配置文件。有关更多信息,请参阅 Systemd 启动计数 - 成功启动
  5. 重启设备:
  6. 检查设备是否使用所创建的部署启动:
    输出:
    要在构建主机上验证新创建的部署,请检查 <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 计数

图:成功启动时的 Systemd-boot 计数

为了在成功启动后管理 systemd-boot 中的启动计数,OSTree 执行以下流程:
  1. 当 OSTree 部署新配置时,它会创建一个名称中带有 +3 标签的配置文件,表示最大重试次数。这将启用启动计数。
  2. systemd-boot 检测到条目文件名中的 +3 标签,并将其重命名为 ostree-conf+2-1.conf,表示已开始一次启动尝试。重命名文件后,启动过程继续。
  3. systemd-bless-boot-generator 创建 systemd-bless-boot.service,该服务被设置为在到达 boot-complete.target 时启动。
  4. systemd-bless-boot.service 通过移除计数标签 +2-1 并将文件重命名为 ostree-conf.conf,将新配置标记为成功。

Systemd 启动计数 - 启动失败和回滚

下图显示了启动失败和回滚时的 systemd-boot 计数流程:
图:启动失败和回滚时的 Systemd-boot 计数

图:启动失败和回滚时的 Systemd-boot 计数

为了在启动失败和回滚后管理 systemd-boot 中的启动计数,OSTree 执行以下流程:
  1. 当 OSTree 部署新配置时,它会创建一个名称中带有 +3 标签的 systemd 配置文件,表示最大重试次数,例如 ostree-boot+3.conf。这将启用启动计数。
  2. systemd-boot 检测到配置文件名中的 +3 标签,并将其重命名为 ostree-boot+2-1.conf,表示已开始一次启动尝试。重命名文件后,启动过程继续。
  3. systemd-bless-boot-generator 创建 systemd-bless-boot.service,该服务在到达 boot-complete.target 时启动。如果 Linux 启动过程中出现任何故障,systemd-bless-boot.service 不会从配置文件中移除 +2-1 计数标签。
  4. 在后续启动中,systemd-boot 检测到配置文件名中的 +2-1 标签,将文件重命名为 ostree-boot+1-2.conf,并尝试以该文件启动。
  5. 如果第二次尝试时 Linux 启动失败,systemd-bless-boot.service 不会从配置文件中移除计数标签 +1-2
  6. 在下一次启动中,systemd-boot 检测到配置文件名中的 +1-2 标签,将文件重命名为 ostree-boot+0-3.conf,并尝试以该文件启动。这是启动 Linux 部署的最后一次尝试。
  7. 如果设备在第三次尝试时未能启动 Linux,systemd-bless-boot.service 不会从配置文件中移除计数标签 +0-3
  8. 在后续启动中,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 镜像中。 要在运行时在持久路径下创建文件和目录,请执行以下操作: 进程在需要时于运行时创建文件或目录。
  1. /run//var/lib//var/cache//var/log/ 下的路径可以通过相应的 systemd 单元文件创建。这里有一份参考
  2. 使用 systemd-tmpfiles 在启动时创建文件、符号链接和目录。
OSTree 在 /usr 处创建只读绑定挂载,确保核心操作系统文件对用户保持不可变。此方法有助于维护系统的完整性和安全性。OSTree 使用 /usr 挂载点来部署下一次更新。
注意
  • OSTree 允许在构建时在 /var/local 路径下安装文件和目录。
  • 尽管 OSTree 保留了构建时安装在 /usr 下的内容,但它不会将安装在 /usr/local 子目录下的内容打包到 rootfs 镜像中。
在启用 OSTree 的 Qualcomm Linux 中,/etc 目录的管理方式同时支持系统更新和本地自定义。
  • /etc 目录是可变的,允许在运行时进行修改,以维护需要在更新之间持久保留的系统配置。
  • OSTree 支持将配置文件从 /usr/etc 目录合并到 /etc。这使得 OSTree 可以更新默认配置,同时保留所做的任何本地更改。
  • 应用更新时,OSTree 会使用文件的原始版本、新更新中的文件版本以及本地修改的文件版本,对 /etc 中的配置文件执行三方合并。
  • 如果合并过程中出现冲突,OSTree 会保留运行时的修改。这有助于维持系统稳定性,并确保关键配置不会被覆盖。

SOTA 发行版功能

软件空中下载(SOTA)发行版功能允许对嵌入式系统和 IoT 设备进行远程更新。它集成了 OSTree 等系统更新工具,使设备无需物理接触即可接收和安装更新。 要在 Qualcomm Linux 中启用 SOTA 发行版功能,运行以下构建命令:
此命令会自动为您的构建配置并启用 SOTA 发行版功能。

后续步骤

使用配方处理树外(out-of-tree)内核模块和设备树:
  • 要构建树外内核模块,请参阅添加内核模块注意 Qualcomm Linux 仅在 custom 变体中支持内核外设备树覆盖(overlay)。
  • 有关设备树/设备树 blob 管理,请参阅平台设备树中的内核 DTB 构建支持。