[PATCH v7 00/17] efi_loader: add capsule update support

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Oct 30 08:54:37 CET 2020


On 10/29/20 5:47 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.

Gitlab CI fails:

https://gitlab.denx.de/u-boot/custodians/u-boot-efi/-/jobs/172745
https://gitlab.denx.de/u-boot/custodians/u-boot-efi/-/jobs/172744

             # Create signature database
             # PK
             check_call('cd %s; openssl req -x509 -sha256 -newkey
rsa:2048 -subj /CN=TEST_PK/ -keyout PK.key -out PK.crt -nodes -days 365'
                        % mnt_point, shell=True)
             check_call('cd %s; %scert-to-efi-sig-list -g %s PK.crt
PK.esl; %ssign-efi-sig-list -t "2020-04-01" -c PK.crt -k PK.key PK
PK.esl PK.auth'
 >                      % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
                        shell=True)
E                      NameError: name 'EFITOOLS_PATH' is not defined
test/py/tests/test_efi_secboot/conftest.py:50: NameError


To get the series merged, please, provide the necessary patches for
.azure-pipelines.yml, .gitlab-ci.yml, .travis.yml.

Possibly you will have to adjust
https://gitlab.denx.de/u-boot/gitlab-ci-runner

Best regards

Heinrich



>
> Quick usage
> ===========
> 1. You can create a capsule file with the following host command:
>
>    $ mkeficapsule [--fit <fit image> | --raw <raw image>] <output file>
>
> 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-#4,#12: preparatory patches
> Patch#5-#11,#13: main part of implementation
> Patch#14-#15: utilities
> Patch#16-#17: pytests
>
> [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.
>
> Please note that the capsule pytest itself won't be run in the CI
> partly because some specific configuration for sandbox build is
> required and partly because there is a problem with virt-make-fs.
> See test_efi_capsule_firmware.py.
>
> 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
>
> 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
> =======
> 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 (17):
>    dfu: rename dfu_tftp_write() to dfu_write_by_name()
>    dfu: modify an argument type for an address
>    common: update: add a generic interface for FIT image
>    dfu: export dfu_list
>    efi_loader: add option to initialise EFI subsystem early
>    efi_loader: add efi_create_indexed_name()
>    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
>    dfu: add dfu_write_by_alt()
>    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
>
>   cmd/efidebug.c                                | 235 +++++
>   common/Kconfig                                |  15 +
>   common/Makefile                               |   3 +-
>   common/board_r.c                              |   6 +
>   common/main.c                                 |   4 +
>   common/update.c                               |  77 +-
>   drivers/dfu/Kconfig                           |   6 +
>   drivers/dfu/Makefile                          |   2 +-
>   drivers/dfu/dfu.c                             |   2 +-
>   drivers/dfu/dfu_alt.c                         | 125 +++
>   drivers/dfu/dfu_tftp.c                        |  65 --
>   include/dfu.h                                 |  57 +-
>   include/efi_api.h                             | 166 ++++
>   include/efi_loader.h                          |  30 +
>   include/image.h                               |  12 +
>   lib/efi_loader/Kconfig                        |  72 ++
>   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                    | 106 +-
>   test/py/tests/test_efi_capsule/conftest.py    |  72 ++
>   test/py/tests/test_efi_capsule/defs.py        |  12 +
>   .../test_efi_capsule/test_capsule_firmware.py | 241 +++++
>   .../tests/test_efi_capsule/uboot_bin_env.its  |  36 +
>   tools/Makefile                                |   2 +
>   tools/mkeficapsule.c                          | 239 +++++
>   27 files changed, 2871 insertions(+), 140 deletions(-)
>   create mode 100644 drivers/dfu/dfu_alt.c
>   delete mode 100644 drivers/dfu/dfu_tftp.c
>   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/uboot_bin_env.its
>   create mode 100644 tools/mkeficapsule.c
>



More information about the U-Boot mailing list