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

AKASHI Takahiro takahiro.akashi at linaro.org
Thu May 7 04:50:58 CEST 2020


On Thu, Apr 30, 2020 at 09:51:51PM +0200, Heinrich Schuchardt wrote:
> 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.

Right. We must ensure that capsule updates immediately must happen
after reboot.

> 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.

Yeah ...

> 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.

Thank you for detailed explanation instead of me!
The UEFI specification sounds a bit odd, but I can't read it
differently than my interpretation.

> 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.

I didn't take this approach because firmware update may affect
not only UEFI subsystem but also other U-Boot functionality.
This is why "capsule updates must happen immediately after reboot."

Thanks,
-Takahiro Akashi

> Best regards
> 
> Heinrich


More information about the U-Boot mailing list