bootstd: Support for distro specific EFI folders

Ilias Apalodimas ilias.apalodimas at linaro.org
Mon Nov 20 08:02:00 CET 2023


Hi Mark,

On Sun, 19 Nov 2023 at 19:38, Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
>
> > Date: Sat, 18 Nov 2023 23:52:11 +0100
> > From: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
>
> Hi Heinrich,
>
> > On 11/18/23 22:28, Shantur Rathore wrote:
> > > Hi Heinrich,
> > >
> > > On Fri, Nov 17, 2023 at 3:12 PM Heinrich Schuchardt
> > > <heinrich.schuchardt at canonical.com> wrote:
> > >>
> > >> On 11/16/23 19:45, Shantur Rathore wrote:
> > >>> On Thu, Nov 16, 2023 at 6:15 PM Heinrich Schuchardt
> > >>> <heinrich.schuchardt at canonical.com> wrote:
> > >>>>
> > >>>> On 11/16/23 17:52, Shantur Rathore wrote:
> > >>>>> Hi Simon,
> > >>>>>
> > >>>>> Currently bootstd - bootmethod_efi only looks for the default
> > >>>>> bootxx64.efi in /EFI/boot folder only.
> > >>>>> Generally many distros end up putting their bootloaders in
> > >>>>> EFI/<distro> folders like EFI/ubuntu and EFI/debian etc.
> > >>>>>
> > >>>>> In x86 worlds, the NVRAM is modified and new boot entries are added to
> > >>>>> support these but in the U-boot world the NVRAM variables are
> > >>>>> read-only.
> > >>>>
> > >>>> I guess you are referring to UEFI boot options. These typically are not
> > >>>> stored in non-volatile RAM but on a SPI flash device.
> > >>>>
> > >>>
> > >>> Thanks for correcting me.
> > >>>
> > >>>>>
> > >>>>> What would be the best way to implement this?
> > >>>>>
> > >>>>> I was thinking of having a "efi_prefixes" environment variable which
> > >>>>> can be set to "ubuntu debian centos" etc and bootmethod_efi can try
> > >>>>> all of them. Will bootmethod_efi be able to support multiple entries (
> > >>>>> thinking of multiboot ) ?
> > >>>>
> > >>>> On my laptop I have:
> > >>>>
> > >>>> EFI/Microsoft/Boot/bootmgr.efi
> > >>>> EFI/Microsoft/Boot/memtest.efi
> > >>>> EFI/Boot/bootx64.efi
> > >>>> EFI/Boot/fbx64.efi
> > >>>> EFI/Boot/mmx64.efi
> > >>>> EFI/debian/shimx64.efi
> > >>>> EFI/debian/grubx64.efi
> > >>>> EFI/debian/mmx64.efi
> > >>>> EFI/debian/fbx64.efi
> > >>>> EFI/ubuntu/grubx64.efi
> > >>>> EFI/ubuntu/shimx64.efi
> > >>>> EFI/ubuntu/mmx64.efi
> > >>>>
> > >>>> Obviously each installed operating system provides multiple EFI binaries
> > >>>> and non uses the fallback file name BOOT<ARCH>.EFI. A value "ubuntu
> > >>>> debian centos" would not be able to describe which file you are looking
> > >>>> for.
> > >>>>
> > >>>> We already have the U-Boot command line eficonfig and efidebug commands
> > >>>> to set up UEFI boot options which can describe which EFI binary to load
> > >>>> and which command line to pass to it. These are considered by the
> > >>>> existing boot flows.
> > >>>
> > >>> So, I am building a new RockPro64 based cluster and using Canonical
> > >>> MAAS to set them up automatically, booting them up using DHCP and
> > >>> installing them over the network.
> > >>> I configured an Armbian image using Packer to be compatible with MAAS
> > >>> and it happily installs it. As part of installation process, a
> > >>> grub-install is run which installs the grub efi,
> > >>> this EFI ends up in EFI/debian instead of expected EFI/boot.
> > >>> To be able to make it boot, I have to add commands to move it to
> > >>> EFI/boot. I am trying to find a way in U-Boot that would allow me to
> > >>> skip this step.
> > >>> With eficonfig if I understand correctly, it would need manual
> > >>> intervention to create boot entries.
> > >>>
> > >>>>
> > >>>> If you are installing the shim-signed package on Ubuntu, the EFI boot
> > >>>> option for Ubuntu is set up by EFI/BOOT/BOOT<ARCH>.EFI using the content
> > >>>> of EFI/ubuntu/BOOT<ARCH>.CSV. This is done before ExitBootServices() and
> > >>>> therefore should work with current U-Boot.
> > >>>>
> > >>>> Patches are pending upstream to make EFI variables writable from Linux
> > >>>> if they are stored in the RPMB partition in the eMMC. See this series:
> > >>>>
> > >>>> https://lore.kernel.org/linux-efi/20231107054057.1893-2-masahisa.kojima@linaro.org/
> > >>>>
> > >>>
> > >>> Would it be possible to save it in SPI Flash as the U-Boot environment ?
> > >>
> > >> Currently this is not supported by U-Boot.
> > >>
> > >> The U-Boot environment variables can be stored in lots of different
> > >> places SPI flash is only one of these. But none of these locations is
> > >> protected from OS access which would be preferable for UEFI variables
> > >> for security reasons.
> > >>
> > >> To support boards without eMMC the right way forward would be writing a
> > >> new implementation of the OP-TEE standalone MM which writes the
> > >> variables to SPI flash instead of the RPMB partition and ensures that
> > >> the SPI flash' MMIO registers are protected against access from the
> > >> non-secure world.
> > >
> > > Thanks for explaining this to me.
> > > This seems like a long way to go, for now what would be an acceptable
> > > solution, some options are
> > >
> > > 1. Allow to set a space separated efi_prefixes (e.g. "boot ubuntu
> > > debian") variable which is ready by bootmeth_efi and used as
> > > efi/<efi_prefix> instead of efi/boot.
> > > 2. Improve bootmeth_efi to find all bootxxxx.efi in efi/ folder and
> > > present all them as bootflows to bootstd.
> >
> > As mentioned in a prior mail ubuntu/bootxxxx.efi and debian/bootxxxx.efi
> > don't exist. I would prefer not to add any distro specific stuff in
> > upstream U-Boot. Instead we will continue to drive what Linaro has
> > suggested to improve U-Boot EFI variables support in Linux.
>
> I agree that adding hacks like this is not a good idea.

+ 1

>
> The Linaro approach that involves OP-TEE makes for a fairly complex
> solution.  And there are plenty of boards that have neither eMMC nor
> SPI flash.  If Secure Boot is not a requirement (and I'd argue that
> for most "hobbyist" boards it isn't) storing the EFI variables in a
> file on the ESP (as implemented by the CONFIG_EFI_VARIABLE_FILE_STORE
> Kconfig option) is a workable alternative.  And this is actually what
> the rockpro64-rk3399_defconfig enables.

Even in that case, preseeding the variables can enable uefi secure
boot. But you have to establish a chain of trust since the
authenticated EFI variables are part of  the u-boot binary.

>
> I noticed that the latest EBBR attempts to standardize this:
>
>   https://arm-software.github.io/ebbr/index.html#document-chapter5-variable-storage
>
> Not sure what the status here is.

Heinrich and I were the ones who proposed the standardization. The
idea is to eventually fix it for all boards and we are working on it,

> But if the Linux kernel folks
> accept that alternative implementations for runtime EFI variable
> access are a thing, then a method that modifies the file would be
> possible as well.  Or maybe it is good enough to implement support for
> this in the efivar library.

Yes to both. I discussed the idea during Linux Plumbers. All
approaches have some pros and cons, you can find some details here
[0].
Implementing support to efitool is straightforward, but a bit too
hacky for my taste. An obvious disadvantage is that it's hard to sync
the kernel/file view after an update.
The plan right now is to investigate overwriting RT functions and use
kernel-provided ones that modify the file (which is probably going to
be passed in a config table)

[0] https://lpc.events/event/17/contributions/1653/

Thanks
/Ilias
>
> That said, Linux distros probably should install their EFI bootloader
> as EFI/BOOT/BOOTxxxx.EFI if that file doesn't exist yet.  Some Linux
> distros already do this.  This would make the distro work "out of the
> box" on a lot more boards.


More information about the U-Boot mailing list