From mboxrd@z Thu Jan 1 00:00:00 1970 From: Heinrich Schuchardt Date: Tue, 24 Nov 2020 22:37:10 +0100 Subject: [PATCH v9 00/11] efi_loader: add capsule update support In-Reply-To: <20201117002805.13902-1-takahiro.akashi@linaro.org> References: <20201117002805.13902-1-takahiro.akashi@linaro.org> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 11/17/20 1:27 AM, AKASHI Takahiro wrote: > Summary > ======= > 'UpdateCapsule' is one of runtime services defined in UEFI specification > and its aim is to allow a caller (OS) to pass information to the firmware, > i.e. U-Boot. This is mostly used to update firmware binary on devices by > instructions from OS. > > While 'UpdateCapsule' is a runtime services function, it is, at least > initially, supported only before exiting boot services alike other runtime > functions, [Get/]SetVariable. This is because modifying storage which may > be shared with OS must be carefully designed and there is no general > assumption that we can do it. > > Therefore, we practically support only "capsule on disk"; any capsule can > be handed over to UEFI subsystem as a file on a specific file system. > > In this patch series, all the related definitions and structures are given > as UEFI specification describes, and basic framework for capsule support > is provided. Currently supported is > * firmware update (Firmware Management Protocol or simply FMP) > > Most of functionality of firmware update is provided by FMP driver and > it can be, by nature, system/platform-specific. So you can and should > implement your own FMP driver(s) based on your system requirements. > Under the current implementation, we provide two basic but generic > drivers with two formats: > * FIT image format (as used in TFTP update and dfu) > * raw image format > > It's totally up to users which one, or both, should be used on users' > system depending on user requirements. > > Quick usage > =========== > 1. You can create a capsule file with the following host command: > > $ mkeficapsule [--fit | --raw ] > > 2. Put the file under: > > /EFI/UpdateCapsule of UEFI system partition > > 3. Specify firmware storage to be updated in "dfu_alt_info" variable > (Please follow README.dfu for details.) > > ==> env set dfu_alt_info '...' > > 4. After setting up UEFI's OsIndications variable, reboot U-Boot: > > OsIndications <= EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED > > Patch structure > =============== > Patch#1-#6: main part of implementation > Patch#7-#8: utilities > Patch#9-#10: pytests > Patch#11: for sandbox test > > [1] https://git.linaro.org/people/takahiro.akashi/u-boot.git efi/capsule > > Prerequisite patches > ==================== > None > > Test > ==== > * passed all the pytests which are included in this patch series > on sandbox build locally. > * In Travis CI, all tests skipped (or 'S', but it's not a failure, 'F') > because "virt-make-fs" cannot be executed. > > 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. > => See patch#5 for my proposal > * A bunch of warnings like > WARNING: Use 'if (IS_ENABLED(CONFIG...))' instead of '#if or #ifdef' > where possible > I don't think that fixing those improves anything. > * Add a document in uefi.rst What is your status for the test running on Gitlab CI? I still see test/py/tests/test_efi_capsule/test_capsule_firmware.py sss [ 0%] in https://gitlab.denx.de/u-boot/custodians/u-boot-efi/-/jobs/182120 Best regards Heinrich > > TODO's > ====== > (Won't be addressed in this series.) > * capsule authentication > * capsule dependency (dependency expression instruction set, or depex) > * 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 > ======= > v9 (November 17, 2020) > * rebased on v2021.01-rc2 > * removed already-merged patches > * aligned with a function prototype change of efi_create_indexed_name() > (Patch#1-2) > # See Travis CI status in v8 below > > v8 (November 13, 2020) > * fix a "not used" warning against update_load() in some configuration > (Patch#3) > * fix failures (marked as 'F') in *secure boot* test in Travis CI by > making "EFI_CAPSULE_ON_DISK_EARLY" 'default n' (Patch#8) > * fix failures (marked as 'E') at pytest setup in Travis CI by changing > a python file's name along with removing unused definitions (Patch#16) > * add Patch#18 to enable tests to be run with default sandbox config > (Patch#18) > > v7 (October 29, 2020) > * rename CONFIG_DFU_ALT to CONFIG_DFU_WRITE_ALT (Patch#1,#3,#13) > > v6 RESEND (October 29, 2020) > * rebased on v2021.01-rc1 > > v6 (September 7, 2020) > * temporarily drop the prerequisite patch[2] > * add a missing field (dependencies) in efi_api.h (but never used) (Patch#10) > * add a missing field (image_capsule_support) and related definitions > in efi_api.h (Patch#10, #15) > * cosmetic changes on constant definitions in efi_api.h (Patch#10) > * strict check for INVALID_PARAMETER at GET_IMAGE_INFO api (Patch#11,#13) > * fix warnings in pytest (Patch#16,#17) > > v5 (August 3, 2020) > * removed superfluous type conversion at dfu_write_from_mem_addr() > (Patch#2) > * introduced a common helper function, efi_create_indexed_name() > (Patch#6,#7,#8) > * use efi_[get|set]_variable_int(), if necessary, with READ_ONLY > (Patch#7,#8) > * return EFI_UNSUPPORTED at Patch#7 > * changed the word, number, to 'index' (Patch#7,#8) > * removed 'ifdef CONFIG_EFI_CAPSULE_ON_DISK' from a header (Patch#8) > * initialize 'CapsuleLast' in efi_init_obj_list() (Patch#7,#8) > * added 'const' qualifier for filename argument at > efi_capsule_[read|delete]_file() (Patch#8) > > v4 (July 22, 2020) > * rebased to Heinrich's current efi-2020-10 > * rework dfu-related code to align with Heinrich's change (Patch#1,#3) > * change a type of 'addr' argument from int to 'void *' per Sughosh's > comment (Patch#2-#3,#11-#12) > * rework/simplify pytests (Patch#15-#16) > - utilize virt-make-fs > - drop Test Case 1 (updating U-Boot environment data) > - remove useless definitions (MNT_PNT, EFI_CAPSULE_IMAGE_NAME) > - apply autopep8 > > v3 (July 10, 2020) > * rebased to Heinrich's current efi-2020-10-rc1 > * refactor efi_firmware_[fit|raw]_get_image_info() (patch#11,#13) > > v2 (June 17, 2020) > * rebased to v2020.07-rc4 > * add preparatory patches for dfu (Patch#1-#5, #12) > * rework FIT capsule driver to utilize dfu_alt_info instead of CONFIG_xxx > (patch#11) > * extend get_image_info() to correspond to dfu_alt_info > (patch#11) > * add a 'raw binary' capsule support > (patch#13, #17) > * allow multiple capsule formats (with different GUIDs) to be installed > (patch#11, #13) > * extend mkeficapsule command to accept additional parameters, like > version/index/hardware instance for a capsule header info. > (patch#15) > * mkeficapsule can now also generate raw-binary capsule > (patch#16) > * add function descriptions > * apply autopep8 to pytests and fix more against pylint > > v1 (April 27, 2020) > * rebased to v2020.07-rc > * removed already-merged patches (RFC's #1 to #4) > * dropped 'variable update' capsule support (RFC's patch#10) > * dropped 'variable configuration table' support (RFC's patch#11) > (Those two should be discussed separately.) > * add preparatory patches (patch#1/#2) > * fix several build errors > * rename some Kconfig options to be aligned with UEFI specification's terms > (patch#3,4,6,7) > * enforce UpdateCapsule API to be disabled after ExitBootServices (patch#3) > * use config table, runtime_services_supported, instead of variable (patch#3) > * make EFI_CAPSULE_ON_DISK buildable even if UpdateCapsule API is disabled > (patch4) > * support OsIndications, invoking capsule-on-disk only if the variable > indicates so (patch#4) > * introduced EFI_CAPSULE_ON_DISK_EARLY to invoke capsule-on-disk in U-Boot > initialization (patch#4) > * detect capsule files only if they are on EFI system partition (patch#4) > * use printf, rather than EFI_PRINT, in error cases (patch#4) > * use 'header_size' field to retrieve capsule data, adding sanity checks > against capsule size (patch#6) > * call fmpt driver interfaces with EFI_CALL (patch#6) > * remove 'variable update capsule'-related code form mkeficapsule (patch#9) > * add a test case of OsIndications not being set properly (patch#10) > * adjust test scenario for EFI_CAPSULE_ON_DISK_EARLY (patch#10) > * revise pytest scripts (patch#10) > > Initial release as RFC (March 17, 2020) > > AKASHI Takahiro (11): > 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 firmware management protocol for FIT image > efi_loader: add firmware management protocol for raw image > cmd: add "efidebug capsule" command > tools: add mkeficapsule command for UEFI capsule update > test/py: efi_capsule: test for FIT image capsule > test/py: efi_capsule: test for raw image capsule > sandbox: enable capsule update for testing > > cmd/efidebug.c | 235 +++++ > common/main.c | 4 + > configs/sandbox64_defconfig | 6 + > configs/sandbox_defconfig | 6 + > include/efi_api.h | 166 ++++ > include/efi_loader.h | 27 + > lib/efi_loader/Kconfig | 68 ++ > lib/efi_loader/Makefile | 2 + > lib/efi_loader/efi_capsule.c | 917 ++++++++++++++++++ > lib/efi_loader/efi_firmware.c | 403 ++++++++ > lib/efi_loader/efi_runtime.c | 104 +- > lib/efi_loader/efi_setup.c | 76 +- > .../py/tests/test_efi_capsule/capsule_defs.py | 5 + > test/py/tests/test_efi_capsule/conftest.py | 74 ++ > .../test_efi_capsule/test_capsule_firmware.py | 241 +++++ > .../tests/test_efi_capsule/uboot_bin_env.its | 36 + > tools/Makefile | 2 + > tools/mkeficapsule.c | 239 +++++ > 18 files changed, 2557 insertions(+), 54 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/capsule_defs.py > create mode 100644 test/py/tests/test_efi_capsule/conftest.py > create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware.py > create mode 100644 test/py/tests/test_efi_capsule/uboot_bin_env.its > create mode 100644 tools/mkeficapsule.c >