
Figure: OTA update for Qualcomm Linux
Firmware update using capsule
Capsule update is a method for updating firmware on Qualcomm Linux-enabled devices. A UEFI capsule packages the firmware into a binary format. When the device boots up and functions in normal mission mode, it downloads and deploys the capsule to the EFI partition. On reboot, during the next bootup cycle, the UEFI processes this capsule and applies the update to the device firmware.OSTree for Linux operating system updates
OSTree is a tool for managing version-controlled, atomic updates of Linux-based operating systems. It works like a git repository for the entire Linux filesystem. OSTree stores snapshots of filesystem trees in repositories, which devices pull over the network. With OSTree, updates are atomic and support rollback, so an interrupted update won’t break the system. IoT and edge devices benefit from secure, consistent updates that allow rollback if something goes wrong.Use capsule and OSTree for complete OTA software updates
To manage firmware and OS updates in a single OTA system, use capsule and OSTree update mechanisms together. Capsule update mechanism handles the firmware updates first, updating the low-level firmware. After the capsule update, the system reboots and reaches Linux OS, where it checks and applies the OSTree updates. Qualcomm Linux uses capsule to update low-level firmware through UEFI. The system follows this procedure to update firmware using capsule:- A binary known as a UEFI capsule encapsulates the firmware update.
- The system delivers the capsule binary to the UEFI by storing it in the mounted
/EFIpath. - The UEFI firmware processes the capsule during the bootup cycle, and applies the update to the device firmware.

Figure: Overview of the storage during OTA update
- Linux OS images
- The
efi.binfile contains the UKI, initrd, and boot loader configuration files. OSTree creates a new configuration file during deployment. It lists the paths to the new kernel and initramfs images copied to the EFI partition. - The
system.imgfile contains the rootfs, including key components, such as/ostree,/ostree/repo, and/ostree/deploy. When a new deployment is created, OSTree updates the filesystem tree to reflect the new version of the operating system. - Firmware images For information related to the list of firmware images, see GitHub.
Update capsule and HLOS
The following figure shows the capsule and high-level operating system (HLOS) update flow:
Figure: Capsule and HLOS update flow
- Copy the
<capsule>.capcapsule file to EFI partition, which is mounted at/boot/EFI/UpdateCapsuleon the booted-up device. - Set the EFI variable (efivar)
OsIndicationsflags withEFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTEDand reboot the device. UEFI performs the following steps when it detects a capsule update request through theOsIndicationsflag:- UEFI identifies that there is a capsule available for update from
OsIndicationsflag. - UEFI authenticates the capsule and updates the firmware images from the capsule.
- The status of capsule update is updated in the EFI system resource table (ESRT).
- If there is a failure during capsule update, UEFI rolls back the firmware to previous version. UEFI successfully updates the firmware from the capsule, and the device boots up with the new firmware.
- UEFI identifies that there is a capsule available for update from
- Copy the OSTree repository to the device. Create a new deployment for HLOS update using OSTree commands, a new configuration file with count tag gets created, reboot the device.
- Systemd-boot picks the new configuration file and boots up the kernel and user space. The device boots up with the updated firmware and the HLOS software.
systemd-bless-boot.servicemarks the new config as good. - Reset the
TrialBootEnabledflag inOtaStatusefivarto indicate firmware is good. UEFI checks this efivar to commit the new firmware.
Update firmware using capsule
The following figure shows the firmware update flow:
Figure: Firmware update using capsule
- To create the
UpdateCapsulefolder on the device, run the following command: - Copy the capsule to the device:
For more information about
firmware_capsule.capcapsule generation, see Capsule generation in UEFI. - Create the
data.hexfile on the device containing the specified hexadecimal data: - Write the contents of
data.hexon the device to the UEFI variableOsIndicationsusing theefivartool:For more information about UEFI variables, see Update and recovery. - Print the value of the
OsIndicationsUEFI variable using theefivartool: - Reboot the device:
- Check the ESRT table entries:
- Check the output of
last_attempt_statuscommand. If it’s 0, then the update is successful: - Check the output of
last_attempt_versioncommand: - Check the output of
fw_versioncommand. Iflast_attempt_versionandfw_versionare the same, then the update is successful:
- Check the output of
Update Linux OS using OSTree
The following figure shows the Linux OS update flow:
Figure: Linux OS update using OSTree
- To check the current deployment in the Qualcomm device, run the following command:
Output:The
*shows the current deployment that the device has booted with. - The
ostree_repopackage is in the<workspace>/build/tmp/deploy/images/<MACHINE>/path on the host development computer. For example,<workspace>/build/tmp/deploy/images/rb3gen2-core-kit/. Copy theostree_repopackage from the host computer to the Qualcomm device using the followingscpcommand: - Pull a local OSTree repository on the Qualcomm device.
To find the
branch_namefor the command, run the following command:Output:In the preceding output,rb3gen2-core-kitis an example branch name. - Create the deployment on the Qualcomm device:
This creates the
ostree-2-poky.confconfiguration file in the/boot/loader/entries/directory. For more information, see Systemd boot counting - Successful boot. - Reboot the device:
- Check if the device is booted with the created deployment:
Output:To verify the newly created deployment on the build host computer, check the deployment in the
<workspace>/build-<DISTRO>/tmp-glibc/work/<MACHINE>/<IMAGE>/ota-sysroot/ostree/deploy/poky/deploypath. For example,<workspace>/build/tmp/work/rb3gen2-core-kit/qcom-multimedia-image/ota-sysroot/ostree/deploy/poky/deploy.
Systemd-boot counting - Successful boot
The following figure shows the systemd-boot counting on successful boot flow:
Figure: Systemd-boot counting on successful boot
- When OSTree deploys a new configuration, it creates a configuration file with a
+3tag in the name, indicating the maximum retry count. This allows boot counting. - systemd-boot detects the
+3tag in the entry file name and renames it toostree-conf+2-1.conf, indicating that one boot attempt has started. After renaming the file, the boot process continues. - The
systemd-bless-boot-generatorcreates thesystemd-bless-boot.service, which is set to start whenboot-complete.targetis reached. - The
systemd-bless-boot.servicemarks the new configuration as successful by removing the counter tags+2-1and renaming the file toostree-conf.conf.
Systemd boot counting - Unsuccessful boot and rollback
Following figure shows the systemd-boot counting on unsuccessful boot and rollback flow:
Figure: Systemd-boot counting on unsuccessful boot and rollback
- When OSTree deploys a new configuration, it creates a systemd configuration file with a
+3tag in the name, indicating the maximum retry count, such asostree-boot+3.conf. This enables boot counting. - systemd-boot detects the
+3tag in the configuration file name and renames it toostree-boot+2-1.conf, indicating that one boot attempt has started. After renaming the file, the boot process continues. - The
systemd-bless-boot-generatorcreates thesystemd-bless-boot.service, which starts whenboot-complete.targetis reached. If there are any failures during the Linux boot-up, thesystemd-bless-boot.servicedoes not remove the+2-1counter tags from the configuration file. - On the subsequent boot, systemd-boot detects the
+2-1tag in the configuration file name, renames the file toostree-boot+1-2.conf, and tries to boot with it. - If the Linux bootup fails on the second attempt, the
systemd-bless-boot.servicedoes not remove the counter tags+1-2from the configuration file. - On the next boot, systemd-boot detects the
+1-2tag in the configuration file name, renames the file toostree-boot+0-3.conf, and tries to boot with it. This is the last attempt to boot Linux deployment. - If the device fails to bootup Linux during the third attempt, the
systemd-bless-boot.servicedoes not remove the counter tags+0-3from the configuration file. - On the subsequent boot, systemd-boot finds the
+0-3tag in the configuration file name. As the counter has reached zero, the entry (configuration file) is considered bad. The systemd-boot reverts to an earlier version by trying the valid configuration file entry.
Usrmerge
The Usrmerge feature in Linux simplifies the filesystem layout by merging certain directories under the/usrpath. It combines /bin, /sbin, and /lib with /usr/bin, /usr/sbin, and /usr/lib, respectively.
With Usrmerge, executables and libraries found in /bin, /sbin, and /lib are placed in /usr/bin, /usr/sbin, and /usr/lib, respectively. The original directories become symbolic links to their /usr counterparts. This unified structure makes maintenance easier and reduces redundancy, as there is only one location for binaries and libraries instead of separate location for root-level and /usr directories. Symbolic links ensure compatibility, allowing scripts and software that reference paths such as /bin to continue functioning.
Linux distributions are adopting Usrmerge to align with the filesystem hierarchy standard (FHS) recommendations and simplify root filesystems, especially in containerized and embedded systems.
Distributions such as Debian, Ubuntu, and Fedora have adopted Usrmerge as part of their system layout, making it a standard in recent versions. The transition involves creating symbolic links and moving any remaining files from the original directories to their /usr equivalents.
Manage /var, /home, /media, /mnt, /opt, /srv, and /usr in Qualcomm Linux
OSTree considers /var as a persistent directory. This means user and runtime created contents under /varremain untouched by OSTree and persist across OTA updates. For more information, see OSTree Overview.
Other directories that remain untouched by OSTree during an OTA update are /home, /media, /mnt, /opt, and /srv. OSTree maps these directories as symbolic links as follows:
/homeis a symbolic link to/var/rootdirs/home/mediais a symbolic link to/var/rootdirs/media/mntis a symbolic link to/var/rootdirs/mnt/optis a symbolic link to/var/rootdirs/opt/srvis a symbolic link to/var/rootdirs/srv
/home, /media, /mnt, /opt, /srv, and /var stays persistent across OTA updates.
To maintain a clean and consistent filesystem, don’t install any artifacts under the preceding directories at build time. Any artifacts installed in these directories during build time are not packaged into the rootfs image generated by the Qualcomm Linux build command, that is, bitbake <image recipe>.
To handle runtime creation of files and directories under persistent paths, do the following:
The process creates the files or directories at runtime when it’s required.
OSTree creates a read only bind mount at
- Paths under
/run/,/var/lib/,/var/cache/, and/var/log/can be created from the respective systemd unit files. Here is a reference.- Use systemd-tmpfiles to create files, symbolic links, and directories at bootup.
/usr, ensuring that the core operating system files remain immutable by users. This approach helps to maintain system integrity and security. OSTree uses the /usr mount-point to deploy next update.
NoteIn Qualcomm Linux with OSTree enabled, the
- OSTree allows the installation of files and directories under the
/var/localpath at build time.- Although OSTree preserves the contents installed under
/usrduring build time, it doesn’t package the contents installed under the/usr/localsubdirectory into the rootfs image.
/etc directory is managed in a way that allows for both system updates and local customizations.
- The
/etcdirectory is mutable, allowing modifications at runtime for maintaining system configurations that need to persist across updates.- OSTree supports merging configuration files from the
/usr/etcdirectory to/etc. This allows OSTree to update default configurations while preserving any local changes made.- When an update is applied, OSTree performs a three-way merge for configuration files in
/etcusing the original version of the file, version of the file in new update and locally modified version of the file.- If conflicts arise during the merge process, OSTree retains the runtime modifications. This helps maintain system stability and ensures that critical configurations aren’t overwritten.
SOTA distribution feature
The software over-the-air (SOTA) distribution feature allows remote updates for embedded systems and IoT devices. It integrates tools such as OSTree for system updates, allowing devices to receive and install updates without physical access. To enable the SOTA distribution feature in Qualcomm Linux, run the following build command:This command automatically configures and enables the SOTA distribution feature for your build.
Next steps
Handle out-of-tree kernel modules and device tree using recipes:- To build an out-of-tree kernel module, see Add a kernel module. Note Qualcomm Linux supports out-of-kernel device tree overlays only for the
customvariant. - For device-tree/device-tree blob management, see DTB build support in kernel in Platform device tree.

