[U-Boot] [RFC, PATCH v4 00/16] efi_loader: non-volatile variables support

AKASHI Takahiro takahiro.akashi at linaro.org
Wed Jul 17 08:25:09 UTC 2019


# In version 4 of this patch set, the implementation is changed to meet
# Wolfgang's requirements.
# I believe that this is NOT intrusive, and that my approach here is NOT
# selfish at all. If Wolfgang doesn't accept this approach, however,
# I would like to go for "Plan B" for UEFI variables implementation.

This patch set is an attempt to implement non-volatile attribute for
UEFI variables. Under the current implementation,
* SetVariable API doesn't recognize non-volatile attribute
* While some variables are defined non-volatile in UEFI specification,
  they are NOT marked as non-volatile in the code.
* env_save() (or "env save" command) allows us to save all the variables
  into persistent storage, but it may cause volatile UEFI variables,
  along with irrelevant U-Boot variables, to be saved unconditionally.

Those observation rationalizes that the implementation of UEFI variables
should be revamped utilizing dedicated storage for them.

Basic ideas:
* Each variable may be labelled with a "context." Variables with
  different contexts will be loaded/saved in different storages.
  Currently, we define two contexts:

    ENVCTX_UBOOT: U-Boot environment variables
    ENVCTX_UEFI: UEFI variables

* Each variable may have a third attribute, "variable storage."
  There are three new flags defined:
  ('flags' are a bit-wise representation of attributes.)

    ENV_FLAGS_VARSTORAGE_VOLATILE: A variable only exists during runtime.
    ENV_FLAGS_VARSTORAGE_NON_VOLATILE: A variable is persistent, but explicit
        "load" and "save" command is required.
    ENV_FLAGS_VARSTORAGE_NON_VOLATILE_AUTOSAVE: A variable is persistent,
        any change will be written back to storage immediately.

* Following those extensions, new interfaces are introduced:
  for hashtable,
    hsearch_r -> hsearch_ext
    hmatch_r  -> hmatch_ext
    hdelete_r -> hdelete_ext
    himport_r -> himport_ext
    hexport_r -> hexport_ext
  for env,
    env_save   -> env_save_ext
    env_load   -> env_load_ext
    env_import -> env_import_ext
    env_export -> env_export_ext
  They will take one or two additional arguments, context and flags,
  comparing with the existing corresponding interfaces.

* Even with those changes, existing interfaces will maintain
  its semantics, as if all the U-Boot environment variables were with
  UEFI_UBOOT context and VARSTORAGE_NON_VOLATILE attribute.
  (The only exception is "env_load()." See below.)

* There is one thing visible to users; *Exported* variables now have
  attribute information, which is appended to variable's name
  in a format of ":xxx"
  For example, 
    => printenv
       arch:san=arm
       baudrate:san=115200
       board:san=qemu-arm
       ...
  This information is necessary to preserve attributes across reboot
  (save/load).

* Each environment storage driver must be modified so as to be aware
  of contexts. (See flash and fat in my patch set.)

Known issues/restriction/TODO:
* Existing interfaces may be marked obsolute or deleted in the future.

* Currently, only flash and fat drivers are modified to support contexts.
* Currently, only fat driver is modified to support UEFI context.

    -> Applying changes to the other drivers is straightforward.

* ENV_IS_NOWHERE doesn't work if we want to disable U-Boot environment,
  but still want to enable UEFI (hence UEFI variables).

    -> One solution would be to add *intermediate* configurations
       to set ENV_IS_NOWHERE properly in such a case.

* Any context won't have VARSTORAGE_NON_VOLATILE and
  VARSTORAGE_NON_VOLATILE_AUTOSAVE entries at the same time. This is
  because it will make "save" operation ugly and unnecessarily complicated
  as we discussed in ML.

    -> In this sense, NON_VOLATILE[or _AUTOSAVE] should be attributed
       to a context itself.

* env_load() may lose some of compatibility; It now always imports variables
  *without* clearing existing entries (i.e. H_NOCLEAR specified) in order
  to support multiple contexts simultaneously.

    -> I have no other good idea to solve this issue.

* Unfortunately, some of existing U-Boot variables seem to be
  "volatile" in nature. For example, we will see errors at boot time:
	...
	Loading Environment from Flash... OK
	## Error inserting "fdtcontroladdr" variable, errno=22
	In:    pl011 at 9000000
	Out:   pl011 at 9000000
	Err:   pl011 at 9000000
	## Error inserting "stdin" variable, errno=22
	## Error inserting "stdout" variable, errno=22
	## Error inserting "stderr" variable, errno=22

    -> We will have to changes their attributes one-by-one.
	(Those can also be set through ENV_FLAGS_LIST_STATIC in env_flags.h).

* As described above, attribute information is visible to users.
  I'm afraid that it might lead to any incompatibility somewhere.
  (I don't notice any issues though.)

* The whole area of storage will be saved at *every* update of
  one UEFI variable. It should be optimized if possible.

* An error during "save" operation may cause inconsistency between cache
  (hash table) and the storage.

    -> This is not UEFI specific though.

* Patch#15 may be unnecessary.

* Add tests if necessary.

Note:
If we need "secure storage" for UEFI variables, efi_get_variable/
efi_get_next_variable_name/efi_set_variable() should be completely replaced
with stub functions to communicate with secure world.
This patch won't affect such an implementation.

Usage:
To enable this feature, the following configs must be enabled:
  CONFIG_ENV_IS_IN_FAT
  CONFIG_ENV_FAT_INTERFACE
  CONFIG_ENV_EFI_FAT_DEVICE_AND_PART
  CONFIG_ENV_EFI_FAT_FILE

You can also define a non-volatile variable from command interface:
=> setenv -e -nv FOO baa

Patch#1 to #5 are to add 'context' support to env interfaces.
Patch#6 to #13 are to add 'variable storage' attribute to env interfaces.
Patch#14 to #16 are to modify UEFI variable implementation to utilize
  new env interfaces.

Changes in v4 (July 17, 2019)
* remove already-merged patches
* revamp after Wolfgang's suggestion

Changes in v3 (June 4, 2019)
* remove already-merged patches
* revamp the code again
* introduce CONFIG_EFI_VARIABLE_USE_ENV for this configuration.
  Once another backing storage, i.e. StMM services for secure boot,
  is supported, another option will be added.

Changes in v2 (Apr 24, 2019)
* rebased on efi-2019-07
* revamp the implementation

v1 (Nov 28, 2018)
* initial

AKASHI Takahiro (16):
  hashtable: extend interfaces to handle entries with context
  env: extend interfaces to import/export U-Boot environment per context
  env: extend interfaces to label variable with context
  env: flash: add U-Boot environment context support
  env: fat: add U-Boot environment context support
  env: add variable storage attribute support
  env: add/expose attribute helper functions for hashtable
  hashtable: import/export entries with flags
  hashtable: extend hdelete_ext for autosave
  env: save non-volatile variables only
  env: save a context immediately if 'autosave' variable is changed
  env: extend interfaces to get/set attributes
  cmd: env: show variable storage attribute in "env flags" command
  env: fat: support UEFI context
  env,efi_loader: define flags for well-known global UEFI variables
  efi_loader: variable: rework with new extended env interfaces

 cmd/nvedit.c                      | 186 ++++++++++++++++++++++--------
 env/Kconfig                       |  42 ++++++-
 env/common.c                      |  82 ++++++++++---
 env/env.c                         |  92 +++++++++++----
 env/fat.c                         | 112 +++++++++++++++---
 env/flags.c                       | 149 +++++++++++++++++++++++-
 env/flash.c                       |  28 +++--
 include/asm-generic/global_data.h |   7 +-
 include/efi_loader.h              |   1 +
 include/env_default.h             |   1 +
 include/env_flags.h               |  63 +++++++++-
 include/environment.h             |  89 ++++++++++++--
 include/exports.h                 |   4 +
 include/search.h                  |  16 +++
 lib/efi_loader/Kconfig            |  12 ++
 lib/efi_loader/Makefile           |   2 +-
 lib/efi_loader/efi_setup.c        |   5 +
 lib/efi_loader/efi_variable.c     |  50 ++++++--
 lib/hashtable.c                   | 143 ++++++++++++++++++++---
 19 files changed, 925 insertions(+), 159 deletions(-)

-- 
2.21.0



More information about the U-Boot mailing list