An update on firmware updates
It’s probably worth mentioning where we are on firmware updates.
A bit of background
One common issue we’ve all had for the last couple of decades is addressing bugs in system and peripheral firmware. For quite some time, machines have had the ability to have their various firmwares updated. Though these mechanisms have existed, they have generally been highly proprietary, and the tools to perform updates have been difficult to use, required manual, in-person operation, had a very different user interface from each vendor, been difficult to mechanically apply to multiple machines, and had various other usability issues. Vendors have solved some of these problems in various ways, sometimes with the result of exacerbating others.
The overall outcome has been that firmware updates are never applied to the overwhelming majority of systems. You may have noticed this on systems of your own. I myself recently discovered I had a laptop firmware that was 54 releases behind current.
So, this has to be made better. And some things have happened that can help make this better!
Things added to system firmware that can help this
UEFI 2.x has a feature called Update Capsule (or sometimes
Capsule updates), implemented with an EFI Runtime Services function
called UpdateCapsule()
. This function is a relatively generic method
to let operating system code running before or after ExitBootServices()
pass a message, identified by a GUID, to the firmware. The message
itself is comprised of a header, which includes some flags and the
GUID, and a scatter-gather list of physical memory addresses (“the
capsule”).
In UEFI 2.5, a separate feature is added in section 22.3 called the EFI System Resource Table, or ESRT. The ESRT is a UEFI configuration table that provides a table of GUIDs to be used in capsule updates, each of which specifies a hardware device which has upgradeable firmware, and associated information such as the current firmware version and status of previous attempts to upgrade that firmware.
Specifically, the ESRT formalizes the GUIDs for use in UpdateCapsule()
calls to initiate a firmware update, with the capsule (i.e. the
scatter-gather list) containing the new firmware. When UpdateCapsule()
is
called with one of these GUIDs, the firmware performs some validation, and
if it is successful, then either an update will initiate immediately, or
it will initiate after a reboot. What this does not provide is
information to be used by the OS to match entries to specific hardware
devices, nor to firmware update files themselves - that all has to be
orchestrated externally. It’s just a list of which GUIDs are upgradeable
with UpdateCapsule()
and the status of the firmware matching each GUID.
Higher level progress
Richard Hughes and I have made a lot of headway on this. Currently we have a couple of projects that can use this data and with which you can initiate firmware updates on some test machines:
- Linux 4.2 exposes the ESRT to userland via sysfs; see gmane or the source or documentation in git for details.
- fwupdate is a simple command line tool and a library which provides the bare functionality of scheduling an update. The command line utility doesn’t do a lot for you; you do something like
fwupdate -a 6c1ce37d-3325-4654-98e2-318b4ca7e174 fwupdate.cap
and it sets up BootNext for you to initiate the firmware update during the next reboot. The main purpose here is to provide libfwupdate.so for other tools to use. Right now this only works with local updates, i.e. you have to have an EFI System Partition, but support for other things like https are planned. - fwupd provides integration between libfwupdate.so and the desktop, and also provides support for keeping track of firmware update packages from your linux distro and matching them up with your hardware, providing useful descriptive text, etc. It provides command line tools that understand the metadata and know when there are new updates available from whomever you’re getting updates from, and extends this functionality into graphical tools and the GNOME Software update system.
- Richard has also made a website with further information, including a (beta) website for uploading firmware to be distributed through distro’s mechanisms, instructions on how to get test accounts, etc. We’re looking for feedback on this and how we can make it as broadly usable as possible, for everyone involved.
So, what's next
Well, next is more system vendors participating, through supporting these interfaces on their machines, providing test machine access so we can be reasonably sure everything works on various platforms, and moving forward on making sure the actual updated firmwares are as widely available as possible by providing feedback on the various tools.
Most of the work on this so far has been done on x86 test machines, because that’s what we have. I have written dummy drivers to test it with OVMF and AAVMF on virtual machines, and verified that the code does at least basically function on Aarch64, but we could really use more support and testing from the ARM community.