[PATCH 1/2] efi_loader: efi_setup: Add efi_start_obj_list() to efi_setup.c
Heinrich Schuchardt
xypron.glpk at gmx.de
Fri Jan 3 20:50:02 CET 2025
On 06.12.24 18:30, Adriano Cordova wrote:
> The command bootefi calls efi_init_obj_list to do the efi set up
> before launching an .efi payload, but efi_init_obj_list is called
> only once. There are some initializations which depend on the
> environment and should be done each time a payload gets launched and
> not only once and can now be done in efi_start_obj_list(). A motivation
> for this change is the following order of events:
>
> 1. Launch an EFI application (e.g. bootefi hello)
> 2. Change the ip address
> 3. Launch another application which uses the pxe protocol
Hello Adriano,
Thanks for addressing this issue.
There are a number of events that can lead to updating the IP address:
* EFI_PXE_BASE_CODE_PROTOCOL.Dhcp()
* EFI_PXE_BASE_CODE_PROTOCOL.SetStationIp()
* EFI_HTTP_PROTOCOL.Configure()
* command set env ethaddr#
* command dhcp
All of these events require:
* Updating the relevant ethaddr* variable.
* Updating any other references to the IP address.
When not only considering EFI applications but also EFI drivers
installed via the bootefi command all of these events can occur during
the runtime of EFI binaries.
Function efi_init_obj_list() is used for setups that are needed only
once before accessing the UEFI sub-system. It is not able to handle events.
If we need to update any internal UEFI data structures, we should do
this instantaneously when the event occurs and not when executing a UEFI
related shell command.
U-Boot already has callbacks invoked when variables are changed. These
are set up with U_BOOT_ENV_CALLBACK(). There is even a command 'env
callbacks' to list these callbacks.
You could define a new function to handle changes of the IP address and
invoke it via U_BOOT_ENV_CALLBACK(ipaddr, <function name>) or
U_BOOT_ENV_CALLBACK(netmask, <function name>).
With lwIP we can have multiple network interfaces. Each has a different
variable ipaddr# assigned to it. We will have to extend the concept of
U_BOOT_ENV_CALLBACK() to allow for wildcard matches by adjusting
find_env_callback(). With CONFIG_REGEX=y regular expressions could be
used for this purpose (cf. include/slre.h) but we should better avoid
the code size increase.
Best regards
Heinrich
>
> As the EFI pxe protocol was initialized when the handles
> for efi net were created in 1., the ip was hardcoded there.
>
> In this example, another possibility would be to make a callback for ip
> address changes to go all the way up to efi_net.
>
> Signed-off-by: Adriano Cordova <adriano.cordova at canonical.com>
> ---
> lib/efi_loader/efi_setup.c | 21 ++++++++++++++++++++-
> 1 file changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
> index aa59bc7779..164586742a 100644
> --- a/lib/efi_loader/efi_setup.c
> +++ b/lib/efi_loader/efi_setup.c
> @@ -12,6 +12,7 @@
> #include <log.h>
> #include <asm-generic/unaligned.h>
>
> +#define OBJ_LIST_INITIALIZED 0
> #define OBJ_LIST_NOT_INITIALIZED 1
>
> efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
> @@ -208,6 +209,18 @@ out:
> return -1;
> }
>
> +/**
> + * efi_start_obj_list() - Start EFI object list
> + *
> + * Return: status code
> + */
> +static efi_status_t efi_start_obj_list(void)
> +{
> + efi_status_t ret = EFI_SUCCESS;
> +
> + return ret;
> +}
> +
> /**
> * efi_init_obj_list() - Initialize and populate EFI object list
> *
> @@ -217,7 +230,9 @@ efi_status_t efi_init_obj_list(void)
> {
> efi_status_t ret = EFI_SUCCESS;
>
> - /* Initialize once only */
> + /* Initialize only once, but start every time if correctly initialized*/
> + if (efi_obj_list_initialized == OBJ_LIST_INITIALIZED)
> + return efi_start_obj_list();
> if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
> return efi_obj_list_initialized;
>
> @@ -349,6 +364,10 @@ efi_status_t efi_init_obj_list(void)
> if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) &&
> !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))
> ret = efi_launch_capsules();
> + if (ret != EFI_SUCCESS)
> + goto out;
> +
> + ret = efi_start_obj_list();
> out:
> efi_obj_list_initialized = ret;
> return ret;
More information about the U-Boot
mailing list