This article will discuss and show you how to recreate a working fwupd service running on Arm, with an accompanying LVFS server to test and deploy your own updates for testing purposes.
Fwupd is a Linux-based firmware update tool initially released in 2015, which has become widely used in the Linux ecosystem by many OEMs to update a variety of firmware types, from game controllers to management engines and servers.
It is used in conjunction with remote servers that provide firmware metadata and downloads, which are controlled either privately by the OEM, or in most instances solely the main public server for fwupd, the Linux Vendor Firmware Service (LVFS), operated and developed by the same core development team.
From its ease of use and pairing with an OEM-friendly web interface that can be used to manage and upload firmware, the use of fwupd within the Linux ecosystem has been increasing consistently. As of December 2021, there have been over 40,000,000 downloads from the LVFS, with 2,000,000 monthly downloads from August, up 50% from three months prior.
As fwupd can utilise the UEFI Capsule-On-Disk standard for on-disk firmware updates, and uses the EFI System Resource Table (ESRT) to track history and version information for UEFI firmware updates, all functionality fwupd requires to function to achieve capsule updates is contained within the Embedded Base Boot Requirements (EBBR) specification, and is compatible with SystemReady certified devices.
Fwupd consists of three main components:
The user space daemon (“fwupd.d”)
The user space tool (“fwupdmgr” or “fwupdtool”)
The fwupd EFI App (“fwupd.efi”)
The user space daemon, “fwupd.d”, handles the fetching and processing of metadata from remote sources such as the LVFS, as well as handling version tracking and history information for UEFI firmware, which is stored in the machine’s ESRT. In addition to this, the daemon also verifies the integrity of the capsules and their contained firmware, and whether an install of a firmware has completed successfully upon restart.
The user space tools, “fwupdmgr” and “fwupdtool”, are simply command line interfaces for the user or developer that allow them to fetch updates, install specified capsule files, and check metadata for debug purposes. For the user, this is most useful for fetching and installing updates from the configured remotes. However, this can also be utilized by developers for verifying packages and signatures, and testing firmware not uploaded to a remote.
Finally, the EFI app (“fwupd.efi”) is used to install UEFI Capsule-On-Disk capsules scheduled for installation by the user space daemon, while also giving the user feedback on the current progress, managing installation failures and erasing the capsule upon successful installation. This must be specifically configured in the boot order as higher priority than Linux.
The prototype consists of a virtual machine running Ubuntu 20.04 on Arm, utilising U-Boot and Trusted Firmware A (“TF-A”). Within this virtual machine, the fwupd daemon and fwupd user space tool run and interact with each other. Outside of that, on the host machine, a local version of the Linux Vendor Firmware Service (“LVFS”) is configured and running.
With regards to the flow of the prototype, the user space tool first requests the daemon for any new updates it can find. After this, the daemon will request however many remotes it has configured for a manifest containing all possible updates for systems. Following this, it will filter for any updates matching the requesting system, and check whether the version is an appropriate upgrade to what is currently installed. The requesting system is identified through a unique GUID generated by the daemon based on the components in the system, and differs depending on which device type is being updated. For UEFI Capsule-On-Disk updates, this identifier is sourced from the "fw_class" entry in the ESRT.
Finally, the daemon will write the firmware into the EFI partition in preparation for an update, and then schedule a restart with the user. On restart, if the EFI app is configured to run first through the BootOrder, then the EFI app will handle the installation, verification of install, and deletion of the capsule. If the vendor opts to not configure the EFI app to run and instead points directly to the capsule for boot, then the capsule will be installed and deleted as it would without the use of the EFI app.
This prototype sets up a virtual machine and environment which follows this flow, and allows for testing of arbitrary update cabinets.
To try this prototype for yourself, you can clone the Gitlab repository, and follow the instructions detailed in the README. The contained scripts have only been tested using Ubuntu 20.04 LTS Focal, with superuser permissions.