[PATCH 04/10] efi_loader: capsule: add capsule_on_disk support

Heinrich Schuchardt xypron.glpk at gmx.de
Thu Apr 30 21:51:51 CEST 2020


On 4/30/20 2:52 PM, Sughosh Ganu wrote:
>
> On Tue, 28 Apr 2020 at 05:58, AKASHI Takahiro
> <takahiro.akashi at linaro.org <mailto:takahiro.akashi at linaro.org>> wrote:
>
>     Heinrich,
>
>     On Mon, Apr 27, 2020 at 10:28:35PM +0200, Heinrich Schuchardt wrote:
>     > On 4/27/20 11:48 AM, AKASHI Takahiro wrote:
>     > > Capsule data can be loaded into the system either via UpdateCapsule
>     > > runtime service or files on a file system (of boot device).
>     > > The latter case is called "capsules on disk", and actual updates
>     will
>     > > take place at the next boot time.
>     > >
>     > > In this commit, we will support capsule on disk mechanism.
>     > >
>     > > Please note that U-Boot itself has no notion of "boot device" and
>     > > all the capsule files to be executed will be detected only if they
>     > > are located in a specific directory, \EFI\UpdateCapsule, on a device
>     > > that is identified as a boot device by "BootXXXX" variables.
>     > >
>     > > Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org
>     <mailto:takahiro.akashi at linaro.org>>
>     > > ---
>     > >  common/main.c                |   4 +
>     > >  include/efi_loader.h         |  16 ++
>     > >  lib/efi_loader/Kconfig       |  22 ++
>     > >  lib/efi_loader/efi_capsule.c | 449
>     +++++++++++++++++++++++++++++++++++
>     > >  lib/efi_loader/efi_setup.c   |   9 +
>     > >  5 files changed, 500 insertions(+)
>     > >
>     > > diff --git a/common/main.c b/common/main.c
>     > > index 06d7ff56d60c..877ae63b708d 100644
>     > > --- a/common/main.c
>     > > +++ b/common/main.c
>     > > @@ -14,6 +14,7 @@
>     > >  #include <env.h>
>     > >  #include <init.h>
>     > >  #include <version.h>
>     > > +#include <efi_loader.h>
>     > >
>     > >  static void run_preboot_environment_command(void)
>     > >  {
>     > > @@ -51,6 +52,9 @@ void main_loop(void)
>     > >     if (IS_ENABLED(CONFIG_UPDATE_TFTP))
>     > >             update_tftp(0UL, NULL, NULL);
>     > >
>     > > +   if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))
>     > > +           efi_launch_capsules();
>     > > +
>     >
>     > Can't we move this to efi_init_obj_list() and do away with
>     > CONFIG_EFI_CAPSULE_ON_DISK_EARLY?
>
>     With CONFIG_EFI_CAPSULE_ON_DISK_EARLY disabled,
>     efi_launch_capsules() will be called in efi_init_obj_list()
>     as you expect. See the code below in efi_setup.c.
>
>
> Instead of calling efi_launch_capsules in efi_init_obj_list, can we
> invoke the function explicitly through a dedicated command line, under
> the 'efidebug capsule' class of commands. I think that would be a
> cleaner approach, since efi_init_obj_list gets called for a lot of efi
> functions, which are unrelated to capsule update.

Who would invoke that command line on an IoT device?

My understanding of the UEFI spec is that capsule updates should be
invoked automatically.

I suggested to Takahiro to use the first EFI system partition that we
find when scanning the available block devices to identify the boot
device holding the capsules but he dismissed it as contradicting the
UEFI spec.

According to the UEFI 2.8 spec we have to first check BootNext and then
BootOrder to find the boot option with the highest priority (just like
the boot manager does). When analysing BootNext and BootOrder we have to
ignore entries pointing to devices that are not present. This gives us
the active boot entry.

On the device identified by the FilePathList field of the active boot
entry we look for the directory \EFI\UpdateCapsule.

The UEFI spec says it does not require to check for other EFI system
partitions. - This could mean it is not forbidden to check other EFI
system partitions for update capsules.

The problem with the UEFI spec is that it assumes that variables
BootNext and BootOrder exist. If they do not exist, the UEFI spec gives
no hint what to do.

One way to solve this is to populate BootOrder with all block devices.
This is exactly what my laptop does:

BootOrder: 0001,0000,0016,0017,0018,0019,001A,001B
Boot0000* Windows Boot Manager
Boot0001* debian
Boot0010  Setup
Boot0011  Boot Menu
Boot0012  Diagnostic Splash Screen
Boot0013  Diagnostics
Boot0014  Startup Interrupt Menu
Boot0015  Rescue and Recovery
Boot0016* USB CD
Boot0017* USB FDD
Boot0018* NVMe0
Boot0019* ATA HDD0
Boot001A* USB HDD
Boot001B* PCI LAN

Please, observe that this list contains entries USB CD, USB FDD, USB HDD
that aren't or even never were physically present on my laptop.

Another approach is just to wait until bootefi or bootm (for EFI FIT
images) is invoked. After loading the boot image but before starting it
we know the active boot device. This will reduce the code size because
we do not have to implement the logic of the boot manager to analyze
BootNext and BootOrder twice.

Best regards

Heinrich


More information about the U-Boot mailing list