From patchwork Tue Mar 17 02:12:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 243717 List-Id: U-Boot discussion From: takahiro.akashi at linaro.org (AKASHI Takahiro) Date: Tue, 17 Mar 2020 11:12:33 +0900 Subject: [RFC 00/14] efi_loader: add capsule update support Message-ID: <20200317021247.5849-1-takahiro.akashi@linaro.org> Summary ======= 'UpdateCapsule' is one of runtime services defined in UEFI specification and its aim is to allow a caller to pass information to the firmware. This is mostly used to update firmware binary on devices by instructions from OS. In this patch series, all the related definitions and structures are given as UEFI specification describes and basic framework for capsule support is implemented. Currently supported types of capsule are * firmware update (Firmware Management Protocol or simply FMP) * variable update UpdateCapsule is a runtime services function, but is, at least initially, provided only before exiting boot services alike other runtime functions. This is because modifying storage which may be shared with OS must be carefully designed and there is no general assumption to do that as in the case of [Get/]SetVariable. Instead, any capsule can be handed over to the firmware as a file on a specific file system. In other words, we only support "capsules on disk" for now. Regarding firmware update, most of functionality is provided by FMP driver and it will be by nature system/platform-specific. So you can and should implement FMP drivers based on your system requirements. In this patch series, only a simple FMP driver based on FIT image for a single region is supported. (So it is "for reference only") See more details in "efi_loader: capsule: add simple firmware management protocol." Regarding variable update, the implementation here is based on a draft proposal[1] by Peter in Boot-arch ML. The specification should be discussed and finalized first. So the code doesn't fully implement Peter's idea. [1] https://lists.linaro.org/pipermail/boot-architecture/2018-October/000883.html Patch structure =============== Patch#1-#4: preparatory patches Patch#5-#11: main part of implementation Patch#12-#14: utilities and tests Test ==== * passed all the pytests which are included in this patch series on sandbox build. * passed Travis CI. Currently, my pytest requires the following prerequisite patch to run without errors: [2] https://lists.denx.de/pipermail/u-boot/2020-March/401726.html [3] https://lists.denx.de/pipermail/u-boot/2020-March/401727.html In addition, you have to enable CONFIG_ENV_IS_IN_SPI_FLASH and CONFIG_SPI_FLASH_SANDBOX to successfully run the test. Issues ====== * Timing of executing capsules-on-disk Currently, processing a capsule is triggered only as part of UEFI subsystem initialization. This means that, for example, firmware update, may not take place at system booting time and will potentially be delayed until a first call of any UEFI functions. TODO's ====== (May or may not be addressed in future versions of this series.) * capsule authentication * capsule dependency (dependency expression instruction set) * loading drivers in a capsule * handling RESET flag in a capsule and QeuryCapsuleCaps * full semantics of ESRT (EFI System Resource Table) * enabling capsule API at runtime * json capsule * recovery from update failure Changes ======= Initial release as RFC (March 17, 2020) AKASHI Takahiro (14): efi_loader: define OsIndicationsSupported flags efi_loader: define System Resource Table macros efi_loader: export a couple of protocol related functions efi_loader: correct a definition of struct efi_capsule_header efi_loader: define UpdateCapsule api efi_loader: capsule: add capsule_on_disk support efi_loader: capsule: add memory range capsule definitions efi_loader: capsule: support firmware update efi_loader: add simple firmware management protocol for FIT image efi_loader: capsule: support variable update efi_loader: variable: export variables table for runtime access cmd: add "efidebug capsule" command tools: add mkeficapsule command for UEFI capsule update test test/py: add efi capsule test cmd/efidebug.c | 234 +++++ include/efi_api.h | 214 ++++- include/efi_loader.h | 53 ++ lib/efi_loader/Kconfig | 65 ++ lib/efi_loader/Makefile | 2 + lib/efi_loader/efi_boottime.c | 29 +- lib/efi_loader/efi_capsule.c | 860 ++++++++++++++++++ lib/efi_loader/efi_firmware.c | 191 ++++ lib/efi_loader/efi_runtime.c | 104 ++- lib/efi_loader/efi_setup.c | 41 +- lib/efi_loader/efi_variable.c | 109 +++ test/py/tests/test_efi_capsule/conftest.py | 109 +++ test/py/tests/test_efi_capsule/defs.py | 21 + .../test_efi_capsule/test_capsule_firmware.py | 102 +++ .../test_efi_capsule/test_capsule_variable.py | 141 +++ test/py/tests/test_efi_capsule/uboot_env.its | 25 + tools/Makefile | 3 + tools/mkeficapsule.c | 501 ++++++++++ 18 files changed, 2744 insertions(+), 60 deletions(-) create mode 100644 lib/efi_loader/efi_capsule.c create mode 100644 lib/efi_loader/efi_firmware.c create mode 100644 test/py/tests/test_efi_capsule/conftest.py create mode 100644 test/py/tests/test_efi_capsule/defs.py create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware.py create mode 100644 test/py/tests/test_efi_capsule/test_capsule_variable.py create mode 100644 test/py/tests/test_efi_capsule/uboot_env.its create mode 100644 tools/mkeficapsule.c