From mboxrd@z Thu Jan 1 00:00:00 1970 From: AKASHI Takahiro Date: Thu, 7 May 2020 11:50:58 +0900 Subject: [PATCH 04/10] efi_loader: capsule: add capsule_on_disk support In-Reply-To: <7a731cad-53c0-2498-109f-aa16092beec4@gmx.de> References: <20200427094829.1140-1-takahiro.akashi@linaro.org> <20200427094829.1140-5-takahiro.akashi@linaro.org> <3121b167-e8e9-d7fd-73ac-5ea7b2f6140d@gmx.de> <20200428002803.GD16947@laputa> <7a731cad-53c0-2498-109f-aa16092beec4@gmx.de> Message-ID: <20200507025058.GJ20621@laputa> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 > > > 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 > > > > > > --- > > > >? 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 > > > >? #include > > > >? #include > > > > +#include > > > > > > > >? 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