[U-Boot] [RFC] efi: variable support

Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported (u64)0
--- cmd/bootefi.c | 3 + include/efi.h | 19 ++++ include/efi_loader.h | 10 ++ lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_runtime.c | 17 ++- lib/efi_loader/efi_util.h | 79 ++++++++++++++ lib/efi_loader/efi_variable.c | 235 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 360 insertions(+), 4 deletions(-) create mode 100644 lib/efi_loader/efi_util.h create mode 100644 lib/efi_loader/efi_variable.c
diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 4f11682..56f6bc4 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -300,6 +300,9 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt) efi_reset_system_init(); efi_get_time_init();
+ /* we don't support much: */ + setenv("efi_61dfe48bca93d211aa0d00e098032b8c_OsIndicationsSupported", "(u64)0"); + /* Call our payload! */ debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry);
diff --git a/include/efi.h b/include/efi.h index 3d58780..f819c5b 100644 --- a/include/efi.h +++ b/include/efi.h @@ -294,6 +294,25 @@ extern char image_base[]; /* Start and end of U-Boot image (for payload) */ extern char _binary_u_boot_bin_start[], _binary_u_boot_bin_end[];
+/* + * Variable Attributes + */ +#define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020 +#define EFI_VARIABLE_APPEND_WRITE 0x0000000000000040 + +#define EFI_VARIABLE_MASK (EFI_VARIABLE_NON_VOLATILE | \ + EFI_VARIABLE_BOOTSERVICE_ACCESS | \ + EFI_VARIABLE_RUNTIME_ACCESS | \ + EFI_VARIABLE_HARDWARE_ERROR_RECORD | \ + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \ + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \ + EFI_VARIABLE_APPEND_WRITE) + /** * efi_get_sys_table() - Get access to the main EFI system table * diff --git a/include/efi_loader.h b/include/efi_loader.h index 99619f5..812ec10 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -176,6 +176,16 @@ efi_status_t __efi_runtime EFIAPI efi_get_time( struct efi_time_cap *capabilities); void efi_get_time_init(void);
+efi_status_t EFIAPI efi_get_variable(s16 *variable_name, + efi_guid_t *vendor, u32 *attributes, + unsigned long *data_size, void *data); +efi_status_t EFIAPI efi_get_next_variable( + unsigned long *variable_name_size, + s16 *variable_name, efi_guid_t *vendor); +efi_status_t EFIAPI efi_set_variable(s16 *variable_name, + efi_guid_t *vendor, u32 attributes, + unsigned long data_size, void *data); + #else /* defined(EFI_LOADER) && !defined(CONFIG_SPL_BUILD) */
/* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 3c230ac..9c67367 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -16,6 +16,7 @@ always := $(efiprogs-y) obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o obj-y += efi_memory.o +obj-y += efi_variable.o obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o obj-$(CONFIG_PARTITIONS) += efi_disk.o diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index dd52755..7615090 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -184,7 +184,16 @@ static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = { /* Clean up system table */ .ptr = &systab.boottime, .patchto = NULL, - }, + }, { + .ptr = &efi_runtime_services.get_variable, + .patchto = &efi_device_error, + }, { + .ptr = &efi_runtime_services.get_next_variable, + .patchto = &efi_device_error, + }, { + .ptr = &efi_runtime_services.set_variable, + .patchto = &efi_device_error, + } };
static bool efi_runtime_tobedetached(void *p) @@ -382,9 +391,9 @@ struct efi_runtime_services __efi_runtime_data efi_runtime_services = { .set_wakeup_time = (void *)&efi_unimplemented, .set_virtual_address_map = &efi_set_virtual_address_map, .convert_pointer = (void *)&efi_invalid_parameter, - .get_variable = (void *)&efi_device_error, - .get_next_variable = (void *)&efi_device_error, - .set_variable = (void *)&efi_device_error, + .get_variable = efi_get_variable, + .get_next_variable = efi_get_next_variable, + .set_variable = efi_set_variable, .get_next_high_mono_count = (void *)&efi_device_error, .reset_system = &efi_reset_system_boottime, }; diff --git a/lib/efi_loader/efi_util.h b/lib/efi_loader/efi_util.h new file mode 100644 index 0000000..a566e81 --- /dev/null +++ b/lib/efi_loader/efi_util.h @@ -0,0 +1,79 @@ +/* + * EFI utils + * + * Copyright (c) 2017 Rob Clark + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __EFI_UTIL_H_ +#define __EFI_UTIL_H_ + +/* + * utf8/utf16 conversion lifted from grub + */ + +static inline int +utf16_strlen(uint16_t *in) +{ + int i; + for (i = 0; in[i]; i++); + return i; +} + +/* Convert UTF-16 to UTF-8. */ +static inline uint8_t * +utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size) +{ + uint32_t code_high = 0; + + while (size--) { + uint32_t code = *src++; + + if (code_high) { + if (code >= 0xDC00 && code <= 0xDFFF) { + /* Surrogate pair. */ + code = ((code_high - 0xD800) << 10) + (code - 0xDC00) + 0x10000; + + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } else { + /* Error... */ + *dest++ = '?'; + /* *src may be valid. Don't eat it. */ + src--; + } + + code_high = 0; + } else { + if (code <= 0x007F) { + *dest++ = code; + } else if (code <= 0x07FF) { + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + } else if (code >= 0xD800 && code <= 0xDBFF) { + code_high = code; + continue; + } else if (code >= 0xDC00 && code <= 0xDFFF) { + /* Error... */ + *dest++ = '?'; + } else if (code < 0x10000) { + *dest++ = (code >> 12) | 0xE0; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } else { + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + } + } + + return dest; +} + + +#endif /* __EFI_UTIL_H_ */ diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c new file mode 100644 index 0000000..5343f49 --- /dev/null +++ b/lib/efi_loader/efi_variable.c @@ -0,0 +1,235 @@ +/* + * EFI utils + * + * Copyright (c) 2017 Rob Clark + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <efi_loader.h> +#include "efi_util.h" + + +/* Mapping between EFI variables and u-boot variables: + * + * efi_$guid_$varname = (type)value + * + * For example: + * + * efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported= + * "(u64)0" + * efi_f3cc021b90a3486683fbe8b6461fc2f2_fdtpath= + * "(string)qcom/apq8016-sbc.dtb" + * + * Possible types: + * + * + string - raw string (TODO automatically converted to utf16?) + * + u64 - hex string encoding 64b value + * + * TODO add other types as needed. + * + * TODO we could include attributes in the value string, ie. something + * like "(ro,boot)(string)qcom/apq8016-sbc.dtb" + * + * TODO we could at least provide read-only access to ->get_variable() + * and friends by snapshot'ing the variables at detach time and having + * alternate versions of ->get_variable() and ->get_next_variable() + * in efi_runtime section. + */ + +#define MAX_VAR_NAME 31 +#define MAX_NATIVE_VAR_NAME (strlen("efi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_") + MAX_VAR_NAME) + +static int hex(unsigned char ch) +{ + if (ch >= 'a' && ch <= 'f') + return ch-'a'+10; + if (ch >= '0' && ch <= '9') + return ch-'0'; + if (ch >= 'A' && ch <= 'F') + return ch-'A'+10; + return -1; +} + +static const char * hex2mem(u8 *mem, const char *hexstr, int count) +{ + memset(mem, 0, count/2); + + do { + int nibble; + + *mem = 0; + + if (!count || !*hexstr) + break; + + nibble = hex(*hexstr); + if (nibble < 0) + break; + + *mem = nibble; + count--; + hexstr++; + + if (!count || !*hexstr) + break; + + nibble = hex(*hexstr); + if (nibble < 0) + break; + + *mem = (*mem << 4) | nibble; + count--; + hexstr++; + mem++; + + } while (1); + + if (*hexstr) + return hexstr; + + return NULL; +} + +static char * mem2hex(char *hexstr, const u8 *mem, int count) +{ + static const char hexchars[] = "0123456789abcdef"; + + while (count-- > 0) { + u8 ch = *mem++; + *hexstr++ = hexchars[ch >> 4]; + *hexstr++ = hexchars[ch & 0xf]; + } + + return hexstr; +} + +/* TODO this ends up byte-swapping the GUID compared to what one might + * expect, so: + * + * efi_61dfe48bca93d211aa0d00e098032b8c_OsIndicationsSupported + * + * instead of + * + * efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported + * + * possibly make logic smarter in converting efi<->native + */ + +static efi_status_t efi_to_native(char *native, s16 *variable_name, + efi_guid_t *vendor) +{ + size_t len; + + len = utf16_strlen((u16 *)variable_name); + if (len >= MAX_VAR_NAME) + return EFI_DEVICE_ERROR; + + native += sprintf(native, "efi_"); + native = mem2hex(native, vendor->b, sizeof(vendor->b)); + native += sprintf(native, "_"); + native = (char *)utf16_to_utf8((u8 *)native, (u16 *)variable_name, len); + *native = '\0'; + + return EFI_SUCCESS; +} + + +static const char * prefix(const char *str, const char *prefix) +{ + while (*str && *prefix) { + if (*str != *prefix) + break; + str++; + prefix++; + } + + if (*prefix) + return NULL; + + return str; +} + + +/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetVariable.28.2... */ +efi_status_t EFIAPI efi_get_variable(s16 *variable_name, + efi_guid_t *vendor, u32 *attributes, + unsigned long *data_size, void *data) +{ + char native_name[MAX_NATIVE_VAR_NAME + 1]; + efi_status_t ret; + unsigned long in_size; + const char *val, *s; + + EFI_ENTRY("%p %p %p %p %p", variable_name, vendor, attributes, + data_size, data); + + if (!variable_name || !vendor || !data_size) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + ret = efi_to_native(native_name, variable_name, vendor); + if (ret) + return EFI_EXIT(ret); + + debug("%s: get '%s'\n", __func__, native_name); + + val = getenv(native_name); + if (!val) + return EFI_EXIT(EFI_NOT_FOUND); + + in_size = *data_size; + + if ((s = prefix(val, "(u64)"))) { + *data_size = sizeof(u64); + + if (in_size < sizeof(u64)) + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + + if (!data) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if (hex2mem(data, s, 16)) + return EFI_EXIT(EFI_DEVICE_ERROR); + + debug("%s: got value: %llu\n", __func__, *(u64 *)data); + } else if ((s = prefix(val, "(string)"))) { + /* TODO should string's be converted to utf16? Or maybe if + * string isn't really a thing in efi, this should be (utf8) + * (and (utf16)?) and (raw%d), with the former being (in the + * land of u-boot) ascii strings converted to utf8/utf16 and + * the latter just being an arbitrary hex encoded value?? + */ + return EFI_EXIT(EFI_DEVICE_ERROR); + } else { + debug("%s: invalid value: '%s'\n", __func__, val); + return EFI_EXIT(EFI_DEVICE_ERROR); + } + // TODO other types? + + // TODO support attributes + if (attributes) + *attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS; + + return EFI_EXIT(EFI_SUCCESS); +} + +/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetNextVariableN... */ +efi_status_t EFIAPI efi_get_next_variable( + unsigned long *variable_name_size, + s16 *variable_name, efi_guid_t *vendor) +{ + EFI_ENTRY("%p %p %p", variable_name_size, variable_name, vendor); + + return EFI_EXIT(EFI_DEVICE_ERROR); +} + +/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#SetVariable.28.2... */ +efi_status_t EFIAPI efi_set_variable(s16 *variable_name, + efi_guid_t *vendor, u32 attributes, + unsigned long data_size, void *data) +{ + EFI_ENTRY("%p %p %x %lu %p", variable_name, vendor, attributes, + data_size, data); + + return EFI_EXIT(EFI_DEVICE_ERROR); +}

On 06/25/2017 12:29 AM, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported (u64)0
Hello Rob,
thank you for your effort for a first implementation of EFI variables.
The UEFI variable runtime services consists of the following functions: GetVariable, GetNextVariableName, SetVariable, QueryVariableInfo.
SetVariable is meant to persistently store variables. The value has to be maintained across reboots.
A variable consists of a variable name, a vendor GUID, an attribute bitmask and the variable value.
SetVariable has to support appending to the value.
The UEFI spec also defines some global variables marked by the EFI_GLOBAL_VARIABLE GUID.
Grub uses UEFI variables to store boot entries for GPT disks.
To do so it requires that the EFI runtime services are available after Linux is booted.
So my conclusion is that it would be valuable to implement the EFI variable services. This implementation has to include a persistent store. The runtime service has to be available after Linux boot.
If we want to manipulate variables from U-Boot we would need two new commands to set and get EFI variable names, GUIDs, attributes, and values.
Could you, please, provide your use case for manipulating EFI variables from U-Boot.
One use case I could think of is to let Linux write the dtb name into an EFI variable and let U-Boot read this EFI variable to decide which dtb file to load.
Best regards
Heinrich Schuchardt

On Sun, Jun 25, 2017 at 1:06 AM, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 06/25/2017 12:29 AM, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported (u64)0
Hello Rob,
thank you for your effort for a first implementation of EFI variables.
The UEFI variable runtime services consists of the following functions: GetVariable, GetNextVariableName, SetVariable, QueryVariableInfo.
SetVariable is meant to persistently store variables. The value has to be maintained across reboots.
A variable consists of a variable name, a vendor GUID, an attribute bitmask and the variable value.
SetVariable has to support appending to the value.
The UEFI spec also defines some global variables marked by the EFI_GLOBAL_VARIABLE GUID.
Grub uses UEFI variables to store boot entries for GPT disks.
To do so it requires that the EFI runtime services are available after Linux is booted.
This is somewhat more ambitious than what I had in mind, at least for the first step or two. By the time linux is loaded, most of u-boot has disappeared from memory, so currently there is very little it can provide as far as runtime services. (I was thinking read-only access to variables might be possible as a 2nd step.)
otoh, at least for systems that have 1+gb of RAM, u-boot is relatively tiny, so a build option to keep all of u-boot in RAM after boot might be a way to approach this.
So my conclusion is that it would be valuable to implement the EFI variable services. This implementation has to include a persistent store. The runtime service has to be available after Linux boot.
It would be nice, and it'd make u-boots implementation (approximation?) of EFI somewhat more complete, for sure.
If we want to manipulate variables from U-Boot we would need two new commands to set and get EFI variable names, GUIDs, attributes, and values.
hmm.. the approach of encoding GUID in variable name and attributes as part of the string value would mean normal getenv/setenv is all we need. This seemed like a more natural approach to me.
Could you, please, provide your use case for manipulating EFI variables from U-Boot.
One use case I could think of is to let Linux write the dtb name into an EFI variable and let U-Boot read this EFI variable to decide which dtb file to load.
I was kinda thinking in the opposite direction, for u-boot to expose dtb name to grub. Also it would be nice for debugging if initial value of grub's debug env var could be read from EFI. For both these cases, read-only access and no runtime access would be sufficient. And from an implementation standpoint, that seemed like a reasonable first goal.
BR, -R

On 06/25/2017 02:12 PM, Rob Clark wrote:
On Sun, Jun 25, 2017 at 1:06 AM, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 06/25/2017 12:29 AM, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported (u64)0
Hello Rob,
thank you for your effort for a first implementation of EFI variables.
The UEFI variable runtime services consists of the following functions: GetVariable, GetNextVariableName, SetVariable, QueryVariableInfo.
SetVariable is meant to persistently store variables. The value has to be maintained across reboots.
A variable consists of a variable name, a vendor GUID, an attribute bitmask and the variable value.
SetVariable has to support appending to the value.
The UEFI spec also defines some global variables marked by the EFI_GLOBAL_VARIABLE GUID.
Grub uses UEFI variables to store boot entries for GPT disks.
To do so it requires that the EFI runtime services are available after Linux is booted.
This is somewhat more ambitious than what I had in mind, at least for the first step or two. By the time linux is loaded, most of u-boot has disappeared from memory, so currently there is very little it can provide as far as runtime services. (I was thinking read-only access to variables might be possible as a 2nd step.)
otoh, at least for systems that have 1+gb of RAM, u-boot is relatively tiny, so a build option to keep all of u-boot in RAM after boot might be a way to approach this.
So my conclusion is that it would be valuable to implement the EFI variable services. This implementation has to include a persistent store. The runtime service has to be available after Linux boot.
It would be nice, and it'd make u-boots implementation (approximation?) of EFI somewhat more complete, for sure.
If we want to manipulate variables from U-Boot we would need two new commands to set and get EFI variable names, GUIDs, attributes, and values.
hmm.. the approach of encoding GUID in variable name and attributes as part of the string value would mean normal getenv/setenv is all we need. This seemed like a more natural approach to me.
Could you, please, provide your use case for manipulating EFI variables from U-Boot.
One use case I could think of is to let Linux write the dtb name into an EFI variable and let U-Boot read this EFI variable to decide which dtb file to load.
I was kinda thinking in the opposite direction, for u-boot to expose dtb name to grub.
The dtb is passed to EFI in memory (2nd parameter of bootefi). So why should grub need the dtb name?
Regards
Heinrich
Also it would be nice for debugging if initial value of grub's debug env var could be read from EFI. For both these cases, read-only access and no runtime access would be sufficient. And from an implementation standpoint, that seemed like a reasonable first goal.
BR, -R

On Sun, Jun 25, 2017 at 1:16 PM, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 06/25/2017 02:12 PM, Rob Clark wrote:
On Sun, Jun 25, 2017 at 1:06 AM, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 06/25/2017 12:29 AM, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported (u64)0
Hello Rob,
thank you for your effort for a first implementation of EFI variables.
The UEFI variable runtime services consists of the following functions: GetVariable, GetNextVariableName, SetVariable, QueryVariableInfo.
SetVariable is meant to persistently store variables. The value has to be maintained across reboots.
A variable consists of a variable name, a vendor GUID, an attribute bitmask and the variable value.
SetVariable has to support appending to the value.
The UEFI spec also defines some global variables marked by the EFI_GLOBAL_VARIABLE GUID.
Grub uses UEFI variables to store boot entries for GPT disks.
To do so it requires that the EFI runtime services are available after Linux is booted.
This is somewhat more ambitious than what I had in mind, at least for the first step or two. By the time linux is loaded, most of u-boot has disappeared from memory, so currently there is very little it can provide as far as runtime services. (I was thinking read-only access to variables might be possible as a 2nd step.)
otoh, at least for systems that have 1+gb of RAM, u-boot is relatively tiny, so a build option to keep all of u-boot in RAM after boot might be a way to approach this.
So my conclusion is that it would be valuable to implement the EFI variable services. This implementation has to include a persistent store. The runtime service has to be available after Linux boot.
It would be nice, and it'd make u-boots implementation (approximation?) of EFI somewhat more complete, for sure.
If we want to manipulate variables from U-Boot we would need two new commands to set and get EFI variable names, GUIDs, attributes, and values.
hmm.. the approach of encoding GUID in variable name and attributes as part of the string value would mean normal getenv/setenv is all we need. This seemed like a more natural approach to me.
Could you, please, provide your use case for manipulating EFI variables from U-Boot.
One use case I could think of is to let Linux write the dtb name into an EFI variable and let U-Boot read this EFI variable to decide which dtb file to load.
I was kinda thinking in the opposite direction, for u-boot to expose dtb name to grub.
The dtb is passed to EFI in memory (2nd parameter of bootefi). So why should grub need the dtb name?
because I want to be able to update dtb w/ 'dnf upgrade' (or equiv cmd for other distros).. the alternative seems to be figuring out how (via distro u-boot script) to find the most recent dtb, or constantly requiring users to upgrade their firmware. Neither of which sounds appealing.
(the whole idea of a single static dtb for a SoC is nice in theory until you realize that complex SoC's like snapdragon are still pushing the boundaries of what we have figured out how to model in dt)
BR, -R

On 06/25/2017 09:06 PM, Rob Clark wrote:
On Sun, Jun 25, 2017 at 1:16 PM, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 06/25/2017 02:12 PM, Rob Clark wrote:
On Sun, Jun 25, 2017 at 1:06 AM, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 06/25/2017 12:29 AM, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported (u64)0
Hello Rob,
thank you for your effort for a first implementation of EFI variables.
The UEFI variable runtime services consists of the following functions: GetVariable, GetNextVariableName, SetVariable, QueryVariableInfo.
SetVariable is meant to persistently store variables. The value has to be maintained across reboots.
A variable consists of a variable name, a vendor GUID, an attribute bitmask and the variable value.
SetVariable has to support appending to the value.
The UEFI spec also defines some global variables marked by the EFI_GLOBAL_VARIABLE GUID.
Grub uses UEFI variables to store boot entries for GPT disks.
To do so it requires that the EFI runtime services are available after Linux is booted.
This is somewhat more ambitious than what I had in mind, at least for the first step or two. By the time linux is loaded, most of u-boot has disappeared from memory, so currently there is very little it can provide as far as runtime services. (I was thinking read-only access to variables might be possible as a 2nd step.)
otoh, at least for systems that have 1+gb of RAM, u-boot is relatively tiny, so a build option to keep all of u-boot in RAM after boot might be a way to approach this.
So my conclusion is that it would be valuable to implement the EFI variable services. This implementation has to include a persistent store. The runtime service has to be available after Linux boot.
It would be nice, and it'd make u-boots implementation (approximation?) of EFI somewhat more complete, for sure.
If we want to manipulate variables from U-Boot we would need two new commands to set and get EFI variable names, GUIDs, attributes, and values.
hmm.. the approach of encoding GUID in variable name and attributes as part of the string value would mean normal getenv/setenv is all we need. This seemed like a more natural approach to me.
Could you, please, provide your use case for manipulating EFI variables from U-Boot.
One use case I could think of is to let Linux write the dtb name into an EFI variable and let U-Boot read this EFI variable to decide which dtb file to load.
I was kinda thinking in the opposite direction, for u-boot to expose dtb name to grub.
The dtb is passed to EFI in memory (2nd parameter of bootefi). So why should grub need the dtb name?
because I want to be able to update dtb w/ 'dnf upgrade' (or equiv cmd for other distros).. the alternative seems to be figuring out how (via distro u-boot script) to find the most recent dtb, or constantly requiring users to upgrade their firmware. Neither of which sounds appealing.
(the whole idea of a single static dtb for a SoC is nice in theory until you realize that complex SoC's like snapdragon are still pushing the boundaries of what we have figured out how to model in dt)
BR, -R
Have a look at Debian/Ubuntu package flash-kernel.
After installing a new kernel update-initramfs triggers flash-kernel. flash-kernel looks up the value provided by file /proc/device-tree/model in a database file to find the correct dtb and installs it in /boot. It further sets a symbolic link /boot/dtb to the dtb. So u-boot can simply load /boot/dtb and pass it to grub.
If static dtbs are not enough for your requirements look at device overlay trees.
Best regards
Heinrich Schuchardt

On Sun, Jun 25, 2017 at 5:07 PM, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 06/25/2017 09:06 PM, Rob Clark wrote:
On Sun, Jun 25, 2017 at 1:16 PM, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 06/25/2017 02:12 PM, Rob Clark wrote:
On Sun, Jun 25, 2017 at 1:06 AM, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 06/25/2017 12:29 AM, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported (u64)0
Hello Rob,
thank you for your effort for a first implementation of EFI variables.
The UEFI variable runtime services consists of the following functions: GetVariable, GetNextVariableName, SetVariable, QueryVariableInfo.
SetVariable is meant to persistently store variables. The value has to be maintained across reboots.
A variable consists of a variable name, a vendor GUID, an attribute bitmask and the variable value.
SetVariable has to support appending to the value.
The UEFI spec also defines some global variables marked by the EFI_GLOBAL_VARIABLE GUID.
Grub uses UEFI variables to store boot entries for GPT disks.
To do so it requires that the EFI runtime services are available after Linux is booted.
This is somewhat more ambitious than what I had in mind, at least for the first step or two. By the time linux is loaded, most of u-boot has disappeared from memory, so currently there is very little it can provide as far as runtime services. (I was thinking read-only access to variables might be possible as a 2nd step.)
otoh, at least for systems that have 1+gb of RAM, u-boot is relatively tiny, so a build option to keep all of u-boot in RAM after boot might be a way to approach this.
So my conclusion is that it would be valuable to implement the EFI variable services. This implementation has to include a persistent store. The runtime service has to be available after Linux boot.
It would be nice, and it'd make u-boots implementation (approximation?) of EFI somewhat more complete, for sure.
If we want to manipulate variables from U-Boot we would need two new commands to set and get EFI variable names, GUIDs, attributes, and values.
hmm.. the approach of encoding GUID in variable name and attributes as part of the string value would mean normal getenv/setenv is all we need. This seemed like a more natural approach to me.
Could you, please, provide your use case for manipulating EFI variables from U-Boot.
One use case I could think of is to let Linux write the dtb name into an EFI variable and let U-Boot read this EFI variable to decide which dtb file to load.
I was kinda thinking in the opposite direction, for u-boot to expose dtb name to grub.
The dtb is passed to EFI in memory (2nd parameter of bootefi). So why should grub need the dtb name?
because I want to be able to update dtb w/ 'dnf upgrade' (or equiv cmd for other distros).. the alternative seems to be figuring out how (via distro u-boot script) to find the most recent dtb, or constantly requiring users to upgrade their firmware. Neither of which sounds appealing.
(the whole idea of a single static dtb for a SoC is nice in theory until you realize that complex SoC's like snapdragon are still pushing the boundaries of what we have figured out how to model in dt)
BR, -R
Have a look at Debian/Ubuntu package flash-kernel.
After installing a new kernel update-initramfs triggers flash-kernel. flash-kernel looks up the value provided by file /proc/device-tree/model in a database file to find the correct dtb and installs it in /boot. It further sets a symbolic link /boot/dtb to the dtb. So u-boot can simply load /boot/dtb and pass it to grub.
but this doesn't work if you want to be able to (for example) unplug a disk from device A and plug it in to device B, does it?
If static dtbs are not enough for your requirements look at device overlay trees.
I do have some interest in overlays, mostly because currently the firmware generates psuedo-random eth/wifi/bt MAC addrs based on some board specific info (like emmc part serial #, for example).. which we currently loose out from if not using the qcom specific lk->kernel boot chain. But I guess that is a bit of a different topic.
BR, -R

On 06/26/2017 12:13 AM, Rob Clark wrote:
(the whole idea of a single static dtb for a SoC is nice in theory until you realize that complex SoC's like snapdragon are still pushing the boundaries of what we have figured out how to model in dt)
BR, -R
Have a look at Debian/Ubuntu package flash-kernel.
After installing a new kernel update-initramfs triggers flash-kernel. flash-kernel looks up the value provided by file /proc/device-tree/model in a database file to find the correct dtb and installs it in /boot. It further sets a symbolic link /boot/dtb to the dtb. So u-boot can simply load /boot/dtb and pass it to grub.
but this doesn't work if you want to be able to (for example) unplug a disk from device A and plug it in to device B, does it?
If static dtbs are not enough for your requirements look at device overlay trees.
I do have some interest in overlays, mostly because currently the firmware generates psuedo-random eth/wifi/bt MAC addrs based on some board specific info (like emmc part serial #, for example).. which we currently loose out from if not using the qcom specific lk->kernel boot chain. But I guess that is a bit of a different topic.
BR, -R
U-Boot can load device tree overlays. Here is what worked for me:
=> load mmc 0:1 0x01000000 dtb 29830 bytes read in 14 ms (2 MiB/s) => fdt addr 0x01000000 0x80000 => load mmc 0:1 0x01080000 rtc.dtbo 529 bytes read in 8 ms (64.5 KiB/s) => fdt apply 0x01080000 => load mmc 0:4 0x13000000 efi/debian/grubaa64.efi reading efi/debian/grubaa64.efi 120832 bytes read in 7 ms (16.5 MiB/s) => bootefi 0x13000000 0x01000000
U-Boot must be configured with CONFIG_OF_LIBFDT_OVERLAY to support device tree overlays.
Best regards
Heinrich Schuchardt

On 25.06.17 00:29, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported (u64)0
That's a pretty nice idea altogether, I agree. I don't think the goal you have in mind is good though.
I don't really think we should ever allow grub to override the device tree files - unless for development purposes. The reason we are in the dt mess we are in today is because it's too easy. People associate device trees with kernels, not hardware. That's just plain wrong: device trees describe hardware, not Linux interfaces.
As for real variable support (for example to boot using a native EFI boot order), I think this approach can work. But before committing to a specific path to take, I'd like to see a full solution that allows us to maintain these variables consistently in runtime services too, as that's required for the boot order.
So far my thinking was that maybe we could push all u-boot variables into EL3. That way we could still call into the same space during Linux execution. However of course only if there is separate storage to put those variables into...
Alex

On Wed, Jul 12, 2017 at 8:57 AM, Alexander Graf agraf@suse.de wrote:
On 25.06.17 00:29, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported (u64)0
That's a pretty nice idea altogether, I agree. I don't think the goal you have in mind is good though.
I don't really think we should ever allow grub to override the device tree files - unless for development purposes. The reason we are in the dt mess we are in today is because it's too easy. People associate device trees with kernels, not hardware. That's just plain wrong: device trees describe hardware, not Linux interfaces.
I kinda wish I could agree with you, but it breaks down quickly when you start getting into more complex SoC's. There is enough that we simply haven't figured out how to model properly in dt. 5yrs from now I might agree with you ;-)
It might mostly sorta work most of the time if u-boot finds the most recent dtb (which at least in fedora would mean parsing all the dtb-x.y.z directory names and figuring out which is newest)
and btw, as someone who works on kernel to the "development purposes" is an important use-case to me.. and generally it isn't a good idea to make kernel developer's boot process significantly different from end users, or you'll just end up in a state where things constantly work for developers and are broken for distros ;-)
As for real variable support (for example to boot using a native EFI boot order), I think this approach can work. But before committing to a specific path to take, I'd like to see a full solution that allows us to maintain these variables consistently in runtime services too, as that's required for the boot order.
persisting variables, especially after we exit boot-services will be... interesting.
Rough idea is move env_htab into __efi_runtime_data and some simple accessors into __efi_runtime. I think we'll need some board support to saveenv after a variable is written. It seems tricky depending on where the variables are stored (ie. if they are on same eMMC that linux thinks it owns).
In some cases it might make sense for u-boot to own eMMC (and hide it from linux) and keep grub and rest of distro media on sd-card / usb-disk / etc. I'm not entirely sure how that would work from kconfig option standpoint, and it would mean that we start adding drivers and a bunch more in the efi_runtime section. (And then how to deal w/ dynamically allocated memory, etc)
BR, -R
So far my thinking was that maybe we could push all u-boot variables into EL3. That way we could still call into the same space during Linux execution. However of course only if there is separate storage to put those variables into...
Alex

On 19.07.17 18:38, Rob Clark wrote:
On Wed, Jul 12, 2017 at 8:57 AM, Alexander Graf agraf@suse.de wrote:
On 25.06.17 00:29, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported
(u64)0
That's a pretty nice idea altogether, I agree. I don't think the goal you have in mind is good though.
I don't really think we should ever allow grub to override the device tree files - unless for development purposes. The reason we are in the dt mess we are in today is because it's too easy. People associate device trees with kernels, not hardware. That's just plain wrong: device trees describe hardware, not Linux interfaces.
I kinda wish I could agree with you, but it breaks down quickly when you start getting into more complex SoC's. There is enough that we simply haven't figured out how to model properly in dt. 5yrs from now I might agree with you ;-)
It's perfectly ok to mismodel things at first. Then the dt would simply contain the "old way" nodes as well as the "new way" ones.
Every time we find a case where this approach does not work, we need to ask ourselves why. And every time we should ideally find a solution so that next time we don't break backwards compatibility.
One good example for that is all of the clock framework mess we have today. As a result of that, Andre started to push that logic into ATF and made Linux just call into it. Conveniently that also fixes issues with
a) partitioning hypervisors b) trustzone controlling devices in the same clock domain as linux
and I'm sure for other cases where we see it fail we will find solutions - at least if people care enough :).
It might mostly sorta work most of the time if u-boot finds the most recent dtb (which at least in fedora would mean parsing all the dtb-x.y.z directory names and figuring out which is newest)
Well, the holy grail would be:
ATF generates DT U-Boot uses that DT to configure itself U-Boot passes the same DT on to Linux
Of course you can cut the chain at any point. And we have to make sure that overrides are always easy enough.
and btw, as someone who works on kernel to the "development purposes" is an important use-case to me.. and generally it isn't a good idea to make kernel developer's boot process significantly different from end users, or you'll just end up in a state where things constantly work for developers and are broken for distros ;-)
I agree :). We still want to have overriding mechanisms. And we do have them today. But the normal end user case should really not force them to have dtbs and kernels in lock-step.
Take a look at all the server platforms out there. They do work with dtb just fine and most of them managed to keep backwards compatibility working. The 2 cases I'm aware of really boiled down to "don't care" attitudes and thus would've been avoidable.
As for real variable support (for example to boot using a native EFI boot order), I think this approach can work. But before committing to a specific path to take, I'd like to see a full solution that allows us to maintain these variables consistently in runtime services too, as that's required for the boot order.
persisting variables, especially after we exit boot-services will be... interesting.
Rough idea is move env_htab into __efi_runtime_data and some simple accessors into __efi_runtime. I think we'll need some board support to saveenv after a variable is written. It seems tricky depending on where the variables are stored (ie. if they are on same eMMC that linux thinks it owns).
In some cases it might make sense for u-boot to own eMMC (and hide it from linux) and keep grub and rest of distro media on sd-card / usb-disk / etc. I'm not entirely sure how that would work from kconfig option standpoint, and it would mean that we start adding drivers and a bunch more in the efi_runtime section. (And then how to deal w/ dynamically allocated memory, etc)
That's why I wanted to push these pieces into EL3, as there's no way anyone can make U-Boot drivers work properly with UEFI's dynamic relocation mess :).
So if you want a "full uefi env" enabled platform, you'd have to steal a storage device completely into the secure world and only drive it from there. U-Boot would only call into EL3 to access that device and handle its own environment though it. Both in the boot time as well as the runtime case.
It really gets tricky if you don't have any dedicated storage available. Then we would be able to expose variables in the boot time case, but not in the runtime one. And I'm not sure how hard that would confuse applications ...
Alex

On Tue, Jul 25, 2017 at 5:38 AM, Alexander Graf agraf@suse.de wrote:
On 19.07.17 18:38, Rob Clark wrote:
On Wed, Jul 12, 2017 at 8:57 AM, Alexander Graf agraf@suse.de wrote:
On 25.06.17 00:29, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported
(u64)0
That's a pretty nice idea altogether, I agree. I don't think the goal you have in mind is good though.
I don't really think we should ever allow grub to override the device tree files - unless for development purposes. The reason we are in the dt mess we are in today is because it's too easy. People associate device trees with kernels, not hardware. That's just plain wrong: device trees describe hardware, not Linux interfaces.
I kinda wish I could agree with you, but it breaks down quickly when you start getting into more complex SoC's. There is enough that we simply haven't figured out how to model properly in dt. 5yrs from now I might agree with you ;-)
It's perfectly ok to mismodel things at first. Then the dt would simply contain the "old way" nodes as well as the "new way" ones.
sometimes, easier said than done
Every time we find a case where this approach does not work, we need to ask ourselves why. And every time we should ideally find a solution so that next time we don't break backwards compatibility.
One good example for that is all of the clock framework mess we have today. As a result of that, Andre started to push that logic into ATF and made Linux just call into it. Conveniently that also fixes issues with
a) partitioning hypervisors b) trustzone controlling devices in the same clock domain as linux
snapdragon has the same issue, but also some clks and regulators, etc, are also used by various other cores on the SoC (dsp's, etc).. for those resources, they actually manage via an "rpm" core (resource power mgr, iirc).
tbh, I think just going the UEFI+ACPI route would, I think, make it much easier for qcom to upstream their firehose of rather complex SoC's by abstracting a lot of the complexity below linux. But not my call.
and I'm sure for other cases where we see it fail we will find solutions - at least if people care enough :).
I agree.. it's just a big task. Which is why I said earlier that I'll agree with your position in 5 yrs ;-)
It might mostly sorta work most of the time if u-boot finds the most recent dtb (which at least in fedora would mean parsing all the dtb-x.y.z directory names and figuring out which is newest)
Well, the holy grail would be:
ATF generates DT U-Boot uses that DT to configure itself U-Boot passes the same DT on to Linux
Of course you can cut the chain at any point. And we have to make sure that overrides are always easy enough.
and btw, as someone who works on kernel to the "development purposes" is an important use-case to me.. and generally it isn't a good idea to make kernel developer's boot process significantly different from end users, or you'll just end up in a state where things constantly work for developers and are broken for distros ;-)
I agree :). We still want to have overriding mechanisms. And we do have them today. But the normal end user case should really not force them to have dtbs and kernels in lock-step.
Take a look at all the server platforms out there. They do work with dtb just fine and most of them managed to keep backwards compatibility working. The 2 cases I'm aware of really boiled down to "don't care" attitudes and thus would've been avoidable.
The idealistic approach that you want is fine for servers and a bunch of other simple industrial SoCs out there.. simply because they are so much less complex. I don't think it is as much of a "don't care" attitude (at least not all of the time).. as much as a whole different level of complexity in the SoC. Trying to say that this approach works for something like am33xx so it ought to work for anyone is just misunderstanding the scope of the problem.
As for real variable support (for example to boot using a native EFI boot order), I think this approach can work. But before committing to a specific path to take, I'd like to see a full solution that allows us to maintain these variables consistently in runtime services too, as that's required for the boot order.
persisting variables, especially after we exit boot-services will be... interesting.
Rough idea is move env_htab into __efi_runtime_data and some simple accessors into __efi_runtime. I think we'll need some board support to saveenv after a variable is written. It seems tricky depending on where the variables are stored (ie. if they are on same eMMC that linux thinks it owns).
In some cases it might make sense for u-boot to own eMMC (and hide it from linux) and keep grub and rest of distro media on sd-card / usb-disk / etc. I'm not entirely sure how that would work from kconfig option standpoint, and it would mean that we start adding drivers and a bunch more in the efi_runtime section. (And then how to deal w/ dynamically allocated memory, etc)
That's why I wanted to push these pieces into EL3, as there's no way anyone can make U-Boot drivers work properly with UEFI's dynamic relocation mess :).
So if you want a "full uefi env" enabled platform, you'd have to steal a storage device completely into the secure world and only drive it from there. U-Boot would only call into EL3 to access that device and handle its own environment though it. Both in the boot time as well as the runtime case.
It really gets tricky if you don't have any dedicated storage available. Then we would be able to expose variables in the boot time case, but not in the runtime one. And I'm not sure how hard that would confuse applications ...
I think for the immediate problem of making an installed OS partition (as opposed to "live media") work, just having variables before we exit runtime services is sufficient. It means, for example, having to edit efivars.txt instead of using grub2-reboot.. but ok, it's a pretty big improvement over the current state.
Post runtime-services is definitely not part of the first patchset.
BR, -R

On 25.07.17 14:47, Rob Clark wrote:
On Tue, Jul 25, 2017 at 5:38 AM, Alexander Graf agraf@suse.de wrote:
On 19.07.17 18:38, Rob Clark wrote:
On Wed, Jul 12, 2017 at 8:57 AM, Alexander Graf agraf@suse.de wrote:
On 25.06.17 00:29, Rob Clark wrote:
Mapping from EFI variables to grub variables. Still almost as many TODOs as lines of code, but just figured I'd send out an early version for comments.
I was thinking of it as a useful way for u-boot to pass values to grub (although grub is still missing a way for grub scripts to retrieve UEFI variables).
The rough idea is to encode GUID + variable name plus "efi_" prefix (to avoid unintended u-boot variables leaking into the UEFI world). And then encode the type (and attributes?) in the string value of the variable. Ie. something like:
setenv efi_8be4df6193ca11d2aa0d00e098032b8c_OsIndicationsSupported
(u64)0
That's a pretty nice idea altogether, I agree. I don't think the goal you have in mind is good though.
I don't really think we should ever allow grub to override the device tree files - unless for development purposes. The reason we are in the dt mess we are in today is because it's too easy. People associate device trees with kernels, not hardware. That's just plain wrong: device trees describe hardware, not Linux interfaces.
I kinda wish I could agree with you, but it breaks down quickly when you start getting into more complex SoC's. There is enough that we simply haven't figured out how to model properly in dt. 5yrs from now I might agree with you ;-)
It's perfectly ok to mismodel things at first. Then the dt would simply contain the "old way" nodes as well as the "new way" ones.
sometimes, easier said than done
Yes, I know :).
Every time we find a case where this approach does not work, we need to ask ourselves why. And every time we should ideally find a solution so that next time we don't break backwards compatibility.
One good example for that is all of the clock framework mess we have today. As a result of that, Andre started to push that logic into ATF and made Linux just call into it. Conveniently that also fixes issues with
a) partitioning hypervisors b) trustzone controlling devices in the same clock domain as linux
snapdragon has the same issue, but also some clks and regulators, etc, are also used by various other cores on the SoC (dsp's, etc).. for those resources, they actually manage via an "rpm" core (resource power mgr, iirc).
tbh, I think just going the UEFI+ACPI route would, I think, make it much easier for qcom to upstream their firehose of rather complex SoC's by abstracting a lot of the complexity below linux. But not my call.
Well, the DT alternative to ACPI byte code are PSCI calls ;).
and I'm sure for other cases where we see it fail we will find solutions - at least if people care enough :).
I agree.. it's just a big task. Which is why I said earlier that I'll agree with your position in 5 yrs ;-)
So any time you come across such a situation, I'd love to hear back on why it was hard. I'm just afraid that if nobody attacks the problems that do arise, we will have the same statement again in 5 years :).
It might mostly sorta work most of the time if u-boot finds the most recent dtb (which at least in fedora would mean parsing all the dtb-x.y.z directory names and figuring out which is newest)
Well, the holy grail would be:
ATF generates DT U-Boot uses that DT to configure itself U-Boot passes the same DT on to Linux
Of course you can cut the chain at any point. And we have to make sure that overrides are always easy enough.
and btw, as someone who works on kernel to the "development purposes" is an important use-case to me.. and generally it isn't a good idea to make kernel developer's boot process significantly different from end users, or you'll just end up in a state where things constantly work for developers and are broken for distros ;-)
I agree :). We still want to have overriding mechanisms. And we do have them today. But the normal end user case should really not force them to have dtbs and kernels in lock-step.
Take a look at all the server platforms out there. They do work with dtb just fine and most of them managed to keep backwards compatibility working. The 2 cases I'm aware of really boiled down to "don't care" attitudes and thus would've been avoidable.
The idealistic approach that you want is fine for servers and a bunch of other simple industrial SoCs out there.. simply because they are so much less complex. I don't think it is as much of a "don't care" attitude (at least not all of the time).. as much as a whole different level of complexity in the SoC. Trying to say that this approach works for something like am33xx so it ought to work for anyone is just misunderstanding the scope of the problem.
Yes, as I mentioned above, I want to learn about all the cases where it went wrong, take a step back and figure out why it was impossible to stay compatible.
Maybe the end result of that will be to dispair and rip all my hair out. But maybe we will find ways to ease the pain next time :).
As for real variable support (for example to boot using a native EFI boot order), I think this approach can work. But before committing to a specific path to take, I'd like to see a full solution that allows us to maintain these variables consistently in runtime services too, as that's required for the boot order.
persisting variables, especially after we exit boot-services will be... interesting.
Rough idea is move env_htab into __efi_runtime_data and some simple accessors into __efi_runtime. I think we'll need some board support to saveenv after a variable is written. It seems tricky depending on where the variables are stored (ie. if they are on same eMMC that linux thinks it owns).
In some cases it might make sense for u-boot to own eMMC (and hide it from linux) and keep grub and rest of distro media on sd-card / usb-disk / etc. I'm not entirely sure how that would work from kconfig option standpoint, and it would mean that we start adding drivers and a bunch more in the efi_runtime section. (And then how to deal w/ dynamically allocated memory, etc)
That's why I wanted to push these pieces into EL3, as there's no way anyone can make U-Boot drivers work properly with UEFI's dynamic relocation mess :).
So if you want a "full uefi env" enabled platform, you'd have to steal a storage device completely into the secure world and only drive it from there. U-Boot would only call into EL3 to access that device and handle its own environment though it. Both in the boot time as well as the runtime case.
It really gets tricky if you don't have any dedicated storage available. Then we would be able to expose variables in the boot time case, but not in the runtime one. And I'm not sure how hard that would confuse applications ...
I think for the immediate problem of making an installed OS partition (as opposed to "live media") work, just having variables before we exit runtime services is sufficient. It means, for example, having to edit efivars.txt instead of using grub2-reboot.. but ok, it's a pretty big improvement over the current state.
Well, it wouldn't be efivars but just the already existing bootenv which can also already be stored in .txt format on SD card ;).
Also, openSUSE has special support for non-efi-var booting. It detects that there is no efi var support and in that case simply installs grub with --removable --no-nvram. That way booting "just works" for the default case that basically everyone cares about.
Post runtime-services is definitely not part of the first patchset.
So yeah, maybe this can work. I definitely don't want to expose any sort of fake RTS variable services, as that would break the logic above ;).
Alex

On Tue, Jul 25, 2017 at 10:25 AM, Alexander Graf agraf@suse.de wrote:
On 25.07.17 14:47, Rob Clark wrote:
On Tue, Jul 25, 2017 at 5:38 AM, Alexander Graf agraf@suse.de wrote:
I agree :). We still want to have overriding mechanisms. And we do have them today. But the normal end user case should really not force them to have dtbs and kernels in lock-step.
Take a look at all the server platforms out there. They do work with dtb just fine and most of them managed to keep backwards compatibility working. The 2 cases I'm aware of really boiled down to "don't care" attitudes and thus would've been avoidable.
The idealistic approach that you want is fine for servers and a bunch of other simple industrial SoCs out there.. simply because they are so much less complex. I don't think it is as much of a "don't care" attitude (at least not all of the time).. as much as a whole different level of complexity in the SoC. Trying to say that this approach works for something like am33xx so it ought to work for anyone is just misunderstanding the scope of the problem.
Yes, as I mentioned above, I want to learn about all the cases where it went wrong, take a step back and figure out why it was impossible to stay compatible.
Maybe the end result of that will be to dispair and rip all my hair out. But maybe we will find ways to ease the pain next time :).
I know recently on one board there were some issues because of the way host and otg usb were muxed (I'm not sure the details, I'm not a usb expert, nor do I have time to be), which at some point will require a non-backwards compatible dt change. In the past it took a while to describe more complex display topologies with bridge chips. There is still the yet unanswered question of how to handle interconnect/NoC bus scaling. Probably other cases that don't come to mind offhand.. I know downstream kernel has a lot of tricks for power saving which we haven't figured out how to do upstream yet.
I think for the immediate problem of making an installed OS partition (as opposed to "live media") work, just having variables before we exit runtime services is sufficient. It means, for example, having to edit efivars.txt instead of using grub2-reboot.. but ok, it's a pretty big improvement over the current state.
Well, it wouldn't be efivars but just the already existing bootenv which can also already be stored in .txt format on SD card ;).
Also, openSUSE has special support for non-efi-var booting. It detects that there is no efi var support and in that case simply installs grub with --removable --no-nvram. That way booting "just works" for the default case that basically everyone cares about.
Post runtime-services is definitely not part of the first patchset.
So yeah, maybe this can work. I definitely don't want to expose any sort of fake RTS variable services, as that would break the logic above ;).
I don't think we have an choice if we want to have cross-distro "firmware", since post-RTS variables aren't going to be possible on all devices, I don't think. Otherwise I would have just stuck with my u-boot hack patch that loads \EFI\fedora\grubaa64.efi directly and not bothered with all this work ;-)
Anyways, it wouldn't really break you.. it would just change the logic above to not do the hack of installing as a live-media image that thinks it owns the whole disk. And then we could install multiple distros on different partitions on the same disk (with the caveat of having to edit efivars.txt to change boot-order... possibly we could invent a u-boot script or bootorder.efi that shows a menu on screen if you boot with some key held down, similar to what you get on x86).
BR, -R

On 25.07.17 17:47, Rob Clark wrote:
On Tue, Jul 25, 2017 at 10:25 AM, Alexander Graf agraf@suse.de wrote:
On 25.07.17 14:47, Rob Clark wrote:
On Tue, Jul 25, 2017 at 5:38 AM, Alexander Graf agraf@suse.de wrote:
I agree :). We still want to have overriding mechanisms. And we do have them today. But the normal end user case should really not force them to have dtbs and kernels in lock-step.
Take a look at all the server platforms out there. They do work with dtb just fine and most of them managed to keep backwards compatibility working. The 2 cases I'm aware of really boiled down to "don't care" attitudes and thus would've been avoidable.
The idealistic approach that you want is fine for servers and a bunch of other simple industrial SoCs out there.. simply because they are so much less complex. I don't think it is as much of a "don't care" attitude (at least not all of the time).. as much as a whole different level of complexity in the SoC. Trying to say that this approach works for something like am33xx so it ought to work for anyone is just misunderstanding the scope of the problem.
Yes, as I mentioned above, I want to learn about all the cases where it went wrong, take a step back and figure out why it was impossible to stay compatible.
Maybe the end result of that will be to dispair and rip all my hair out. But maybe we will find ways to ease the pain next time :).
I know recently on one board there were some issues because of the way host and otg usb were muxed (I'm not sure the details, I'm not a usb expert, nor do I have time to be), which at some point will require a non-backwards compatible dt change. In the past it took a while to describe more complex display topologies with bridge chips. There is still the yet unanswered question of how to handle interconnect/NoC bus scaling. Probably other cases that don't come to mind offhand.. I know downstream kernel has a lot of tricks for power saving which we haven't figured out how to do upstream yet.
I think for the immediate problem of making an installed OS partition (as opposed to "live media") work, just having variables before we exit runtime services is sufficient. It means, for example, having to edit efivars.txt instead of using grub2-reboot.. but ok, it's a pretty big improvement over the current state.
Well, it wouldn't be efivars but just the already existing bootenv which can also already be stored in .txt format on SD card ;).
Also, openSUSE has special support for non-efi-var booting. It detects that there is no efi var support and in that case simply installs grub with --removable --no-nvram. That way booting "just works" for the default case that basically everyone cares about.
Post runtime-services is definitely not part of the first patchset.
So yeah, maybe this can work. I definitely don't want to expose any sort of fake RTS variable services, as that would break the logic above ;).
I don't think we have an choice if we want to have cross-distro "firmware", since post-RTS variables aren't going to be possible on all devices, I don't think. Otherwise I would have just stuck with my u-boot hack patch that loads \EFI\fedora\grubaa64.efi directly and not bothered with all this work ;-)
Anyways, it wouldn't really break you.. it would just change the logic above to not do the hack of installing as a live-media image that thinks it owns the whole disk. And then we could install multiple distros on different partitions on the same disk (with the caveat of having to edit efivars.txt to change boot-order... possibly we could invent a u-boot script or bootorder.efi that shows a menu on screen if you boot with some key held down, similar to what you get on x86).
No, we either implement real EFI vars to Linux or none at all, but I don't want to see us reinvent random non-UEFI standard ways of doing what people expect it to do.
So while yes, before exit_boot_services I think we can expose efi variables, I definitely don't want to see anything "fake" or "different from standard UEFI" within Linux. And that only works with dedicated (or virtualized) storage.
I can understand that it feels appealing to only have a small hack in Linux to get the full UEFI greatness, but I really believe we should either stick to the spec or not expose functionality at all. Anything in between will result in terrible divergence, breakage and means we're still not compliant - which goes against the whole idea.
Of course if instead you're interested to change the UEFI spec to standardize an alternative mechanism for variable storage, I'm all ears :).
Alex

On Tue, Jul 25, 2017 at 12:55 PM, Alexander Graf agraf@suse.de wrote:
On 25.07.17 17:47, Rob Clark wrote:
On Tue, Jul 25, 2017 at 10:25 AM, Alexander Graf agraf@suse.de wrote:
On 25.07.17 14:47, Rob Clark wrote:
On Tue, Jul 25, 2017 at 5:38 AM, Alexander Graf agraf@suse.de wrote:
I agree :). We still want to have overriding mechanisms. And we do have them today. But the normal end user case should really not force them to have dtbs and kernels in lock-step.
Take a look at all the server platforms out there. They do work with dtb just fine and most of them managed to keep backwards compatibility working. The 2 cases I'm aware of really boiled down to "don't care" attitudes and thus would've been avoidable.
The idealistic approach that you want is fine for servers and a bunch of other simple industrial SoCs out there.. simply because they are so much less complex. I don't think it is as much of a "don't care" attitude (at least not all of the time).. as much as a whole different level of complexity in the SoC. Trying to say that this approach works for something like am33xx so it ought to work for anyone is just misunderstanding the scope of the problem.
Yes, as I mentioned above, I want to learn about all the cases where it went wrong, take a step back and figure out why it was impossible to stay compatible.
Maybe the end result of that will be to dispair and rip all my hair out. But maybe we will find ways to ease the pain next time :).
I know recently on one board there were some issues because of the way host and otg usb were muxed (I'm not sure the details, I'm not a usb expert, nor do I have time to be), which at some point will require a non-backwards compatible dt change. In the past it took a while to describe more complex display topologies with bridge chips. There is still the yet unanswered question of how to handle interconnect/NoC bus scaling. Probably other cases that don't come to mind offhand.. I know downstream kernel has a lot of tricks for power saving which we haven't figured out how to do upstream yet.
I think for the immediate problem of making an installed OS partition (as opposed to "live media") work, just having variables before we exit runtime services is sufficient. It means, for example, having to edit efivars.txt instead of using grub2-reboot.. but ok, it's a pretty big improvement over the current state.
Well, it wouldn't be efivars but just the already existing bootenv which can also already be stored in .txt format on SD card ;).
Also, openSUSE has special support for non-efi-var booting. It detects that there is no efi var support and in that case simply installs grub with --removable --no-nvram. That way booting "just works" for the default case that basically everyone cares about.
Post runtime-services is definitely not part of the first patchset.
So yeah, maybe this can work. I definitely don't want to expose any sort of fake RTS variable services, as that would break the logic above ;).
I don't think we have an choice if we want to have cross-distro "firmware", since post-RTS variables aren't going to be possible on all devices, I don't think. Otherwise I would have just stuck with my u-boot hack patch that loads \EFI\fedora\grubaa64.efi directly and not bothered with all this work ;-)
Anyways, it wouldn't really break you.. it would just change the logic above to not do the hack of installing as a live-media image that thinks it owns the whole disk. And then we could install multiple distros on different partitions on the same disk (with the caveat of having to edit efivars.txt to change boot-order... possibly we could invent a u-boot script or bootorder.efi that shows a menu on screen if you boot with some key held down, similar to what you get on x86).
No, we either implement real EFI vars to Linux or none at all, but I don't want to see us reinvent random non-UEFI standard ways of doing what people expect it to do.
So while yes, before exit_boot_services I think we can expose efi variables, I definitely don't want to see anything "fake" or "different from standard UEFI" within Linux. And that only works with dedicated (or virtualized) storage.
I wasn't planning to expose efi vars to linux (or anything post EBS). My rough plan was to persist all the env vars that start with efi_ in EBS while we still have u-boot drivers, to make them available on next boot, but *only* to shim/fallback/grub.. not post-EBS.
Like I said earlier, on devices without a proper way to do efi vars, you have to 'sudo vim /boot/efi/efivars.txt' instead of 'grub2-reboot 2', etc.
BR, -R
I can understand that it feels appealing to only have a small hack in Linux to get the full UEFI greatness, but I really believe we should either stick to the spec or not expose functionality at all. Anything in between will result in terrible divergence, breakage and means we're still not compliant
- which goes against the whole idea.
Of course if instead you're interested to change the UEFI spec to standardize an alternative mechanism for variable storage, I'm all ears :).
Alex

Am 25.07.2017 um 19:23 schrieb Rob Clark robdclark@gmail.com:
On Tue, Jul 25, 2017 at 12:55 PM, Alexander Graf agraf@suse.de wrote:
On 25.07.17 17:47, Rob Clark wrote:
On Tue, Jul 25, 2017 at 10:25 AM, Alexander Graf agraf@suse.de wrote:
On 25.07.17 14:47, Rob Clark wrote:
On Tue, Jul 25, 2017 at 5:38 AM, Alexander Graf agraf@suse.de wrote:
I agree :). We still want to have overriding mechanisms. And we do have them today. But the normal end user case should really not force them to have dtbs and kernels in lock-step.
Take a look at all the server platforms out there. They do work with dtb just fine and most of them managed to keep backwards compatibility working. The 2 cases I'm aware of really boiled down to "don't care" attitudes and thus would've been avoidable.
The idealistic approach that you want is fine for servers and a bunch of other simple industrial SoCs out there.. simply because they are so much less complex. I don't think it is as much of a "don't care" attitude (at least not all of the time).. as much as a whole different level of complexity in the SoC. Trying to say that this approach works for something like am33xx so it ought to work for anyone is just misunderstanding the scope of the problem.
Yes, as I mentioned above, I want to learn about all the cases where it went wrong, take a step back and figure out why it was impossible to stay compatible.
Maybe the end result of that will be to dispair and rip all my hair out. But maybe we will find ways to ease the pain next time :).
I know recently on one board there were some issues because of the way host and otg usb were muxed (I'm not sure the details, I'm not a usb expert, nor do I have time to be), which at some point will require a non-backwards compatible dt change. In the past it took a while to describe more complex display topologies with bridge chips. There is still the yet unanswered question of how to handle interconnect/NoC bus scaling. Probably other cases that don't come to mind offhand.. I know downstream kernel has a lot of tricks for power saving which we haven't figured out how to do upstream yet.
I think for the immediate problem of making an installed OS partition (as opposed to "live media") work, just having variables before we exit runtime services is sufficient. It means, for example, having to edit efivars.txt instead of using grub2-reboot.. but ok, it's a pretty big improvement over the current state.
Well, it wouldn't be efivars but just the already existing bootenv which can also already be stored in .txt format on SD card ;).
Also, openSUSE has special support for non-efi-var booting. It detects that there is no efi var support and in that case simply installs grub with --removable --no-nvram. That way booting "just works" for the default case that basically everyone cares about.
Post runtime-services is definitely not part of the first patchset.
So yeah, maybe this can work. I definitely don't want to expose any sort of fake RTS variable services, as that would break the logic above ;).
I don't think we have an choice if we want to have cross-distro "firmware", since post-RTS variables aren't going to be possible on all devices, I don't think. Otherwise I would have just stuck with my u-boot hack patch that loads \EFI\fedora\grubaa64.efi directly and not bothered with all this work ;-)
Anyways, it wouldn't really break you.. it would just change the logic above to not do the hack of installing as a live-media image that thinks it owns the whole disk. And then we could install multiple distros on different partitions on the same disk (with the caveat of having to edit efivars.txt to change boot-order... possibly we could invent a u-boot script or bootorder.efi that shows a menu on screen if you boot with some key held down, similar to what you get on x86).
No, we either implement real EFI vars to Linux or none at all, but I don't want to see us reinvent random non-UEFI standard ways of doing what people expect it to do.
So while yes, before exit_boot_services I think we can expose efi variables, I definitely don't want to see anything "fake" or "different from standard UEFI" within Linux. And that only works with dedicated (or virtualized) storage.
I wasn't planning to expose efi vars to linux (or anything post EBS). My rough plan was to persist all the env vars that start with efi_ in EBS while we still have u-boot drivers, to make them available on next boot, but *only* to shim/fallback/grub.. not post-EBS.
Like I said earlier, on devices without a proper way to do efi vars, you have to 'sudo vim /boot/efi/efivars.txt'
There shouldn't be efivars - the efi variables should get persisted through saveenv.
instead of 'grub2-reboot 2', etc.
Yup, and that much sounds reasonable to me :). We have to be very careful to not create a special, parallel UEFI world with this though ;).
As an example: I can imagine that once this works, someone will send patches to grub to modify env.txt if it finds a u-boot uefi implementation. And then we by accident created a parallel universe where uefi lost its unification :/.
Alex

On Tue, Jul 25, 2017 at 1:29 PM, Alexander Graf agraf@suse.de wrote:
Am 25.07.2017 um 19:23 schrieb Rob Clark robdclark@gmail.com:
On Tue, Jul 25, 2017 at 12:55 PM, Alexander Graf agraf@suse.de wrote:
On 25.07.17 17:47, Rob Clark wrote:
On Tue, Jul 25, 2017 at 10:25 AM, Alexander Graf agraf@suse.de wrote:
On 25.07.17 14:47, Rob Clark wrote:
> On Tue, Jul 25, 2017 at 5:38 AM, Alexander Graf agraf@suse.de wrote: > > > I agree :). We still want to have overriding mechanisms. And we do have > them > today. But the normal end user case should really not force them to > have > dtbs and kernels in lock-step. > > Take a look at all the server platforms out there. They do work with > dtb > just fine and most of them managed to keep backwards compatibility > working. > The 2 cases I'm aware of really boiled down to "don't care" attitudes > and > thus would've been avoidable.
The idealistic approach that you want is fine for servers and a bunch of other simple industrial SoCs out there.. simply because they are so much less complex. I don't think it is as much of a "don't care" attitude (at least not all of the time).. as much as a whole different level of complexity in the SoC. Trying to say that this approach works for something like am33xx so it ought to work for anyone is just misunderstanding the scope of the problem.
Yes, as I mentioned above, I want to learn about all the cases where it went wrong, take a step back and figure out why it was impossible to stay compatible.
Maybe the end result of that will be to dispair and rip all my hair out. But maybe we will find ways to ease the pain next time :).
I know recently on one board there were some issues because of the way host and otg usb were muxed (I'm not sure the details, I'm not a usb expert, nor do I have time to be), which at some point will require a non-backwards compatible dt change. In the past it took a while to describe more complex display topologies with bridge chips. There is still the yet unanswered question of how to handle interconnect/NoC bus scaling. Probably other cases that don't come to mind offhand.. I know downstream kernel has a lot of tricks for power saving which we haven't figured out how to do upstream yet.
I think for the immediate problem of making an installed OS partition (as opposed to "live media") work, just having variables before we exit runtime services is sufficient. It means, for example, having to edit efivars.txt instead of using grub2-reboot.. but ok, it's a pretty big improvement over the current state.
Well, it wouldn't be efivars but just the already existing bootenv which can also already be stored in .txt format on SD card ;).
Also, openSUSE has special support for non-efi-var booting. It detects that there is no efi var support and in that case simply installs grub with --removable --no-nvram. That way booting "just works" for the default case that basically everyone cares about.
Post runtime-services is definitely not part of the first patchset.
So yeah, maybe this can work. I definitely don't want to expose any sort of fake RTS variable services, as that would break the logic above ;).
I don't think we have an choice if we want to have cross-distro "firmware", since post-RTS variables aren't going to be possible on all devices, I don't think. Otherwise I would have just stuck with my u-boot hack patch that loads \EFI\fedora\grubaa64.efi directly and not bothered with all this work ;-)
Anyways, it wouldn't really break you.. it would just change the logic above to not do the hack of installing as a live-media image that thinks it owns the whole disk. And then we could install multiple distros on different partitions on the same disk (with the caveat of having to edit efivars.txt to change boot-order... possibly we could invent a u-boot script or bootorder.efi that shows a menu on screen if you boot with some key held down, similar to what you get on x86).
No, we either implement real EFI vars to Linux or none at all, but I don't want to see us reinvent random non-UEFI standard ways of doing what people expect it to do.
So while yes, before exit_boot_services I think we can expose efi variables, I definitely don't want to see anything "fake" or "different from standard UEFI" within Linux. And that only works with dedicated (or virtualized) storage.
I wasn't planning to expose efi vars to linux (or anything post EBS). My rough plan was to persist all the env vars that start with efi_ in EBS while we still have u-boot drivers, to make them available on next boot, but *only* to shim/fallback/grub.. not post-EBS.
Like I said earlier, on devices without a proper way to do efi vars, you have to 'sudo vim /boot/efi/efivars.txt'
There shouldn't be efivars - the efi variables should get persisted through saveenv.
hmm, possibly.. that would be simpler.. I had mainly wanted to separate efi and u-boot state, but I think I could go either way on that.
instead of 'grub2-reboot 2', etc.
Yup, and that much sounds reasonable to me :). We have to be very careful to not create a special, parallel UEFI world with this though ;).
btw, I realized I think some of the confusion was my fault.. I probably had previously mentioned the possible 2nd step of moving some of env block into efi_runtime section to make read-only efi variables available to linux.. but without mentioning that I have no immediate plans to actually implement that (and I can't really think of a reason that would be useful). (If there *was* a use-case for that, I think the opensuse installer could detect that by trying to *write* an efi var, I guess.. but really my main interest right now is to have efi vars for pre-EBS).
As an example: I can imagine that once this works, someone will send patches to grub to modify env.txt if it finds a u-boot uefi implementation. And then we by accident created a parallel universe where uefi lost its unification :/.
grub is pre-EBS so it can just use the normal UEFI interfaces. If you do see such a patch, pls NAK it ;-)
BR, -R
participants (3)
-
Alexander Graf
-
Heinrich Schuchardt
-
Rob Clark