Hi Grant,

[who is 'nd'?]

On Wed, 30 Sep 2020 at 09:26, Grant Likely <grant.lik...@arm.com> wrote:
>
> Hi Simon,
>
> Heinrich provided some great answers on the technical details. I'll try
> not to retrace his answers, but there are a few conceptual model bits
> that I think are worth talking about...
>
> On 28/09/2020 17:51, Simon Glass wrote:
> > Hi,
> >
> > I thought perhaps it might be worth starting a thread on this, as
> > despite Grant and Heinrich kinding spending a bit of time talking
> > about this, I am still very much in the dark about how 'embedded' and
> > distro/other boot flows are going to come together with EBBR. Of
> > course this would be easier f2f.
>
> I'll assume for both of the cases you describe below that the UEFI boot
> path (bootefi) is used instead of the traditional bootm.

Well in fact it is either bootm (ARM + x86) or zboot (x86) depending
on what we are talking about.

>
> > Case 1:
> > Firmware loads the kernel to a particular address, selects DT and
> > boots it. The kernel may require EFI boot services, or may not, but in
> > the general case the firmware provides them.
> >
> > Case 2:
> > Firmware loads EFI app and provides EFI boot services to it. How the
> > system actually boots is under control of the app.
> As far as bootefi is concerned, case 1 & case 2 are identical. The image
> to be run is loaded into memory and bootefi executes the payload. In
> case 1 the payload in Linux's built-in UEFI stub. In case 2 the payload
> is grub.efi, shell.efi, shim.efi, etc.
>
> bootefi differs from bootm in that instead of a bare vmlinuz image or a
> FIT image, the loaded image is a PECOFF executable. U=Boot parses the
> PECOFF headers, loads the sections into memory and jumps to the entry
> point. It also leaves a pointer to an in-memory information table with
> callbacks into firmware functions for accessing basic services (console,
> block device, network, graphics, filesystem, etc).
>
> If the image is Linux, then the stub will do a small amount of setup
> before calling ExitBootServices(), which tells firmware to stop managing
> hardware because the kernel is taking over. (In UEFI terms, this is call
> an "OS loader" image)
>
> If the image is a transient binary like Grub or the UEFI shell, it can
> use firmware facilities to load additional files (e.g., initrd, kernel,
> etc) before jumping into another PE/COFF binary. For example, Grub will
> typically load the kernel into memory, which itself is a PE/COFF image,
> and then jump to its entry point.

Yes. I think this is the source of the pain, since there is really no
limit on what these can do and there is no standard flow. Much of the
loading happens outside the control of the bootloader, which means
that verified boot and testing are harder.

>
> If an image doesn't call ExitBootServices(), and instead exits, control
> returns to firmware as one would expect.
>
> > I feel that a lot of the confusion about verified boot, DT selections,
> > boot menus, etc. is coming from the introduction of an EFI app which
> > has no specification (it can be grub, shim or something else, as I
> > understand it). Certainly this is very flexible and future-proof, but
> > it is also arbitrarily complex, unpredictable and hard to secure.
>
> Of the items you've listed above, DT selection does indeed need work,
> but the rest is quite well specified. The UEFI spec has very clear
> specifications on how the boot image is selected via the BOOTxxxx
> variables and the format of the binaries. Secure Boot is also
> standardized so that when Secure Boot is turned on, firmware will only
> execute images signed by a recognized key.
>
> It is no more arbitrarily complex than booting an OS kernel. When
> compared against bootm, both boot flows load an image into memory, and
> both jump to the image starting point. In both cases the OS can do
> whatever it wants after the firmware jumps into it, and in both cases if
> security is enabled then the binaries must be signed.

I think you are missing my point. With bootm etc. it jumps straight
from U-Boot to linux. Of course linux may have an EFI shim, but there
is no grub or any other loader 'in the way'.

>
> Where UEFI differs is that it continues to offer {console,net,block,fs}
> services for as long as the image chooses to use them so that early boot
> code doesn't need to carry its own implementations.

Yes. Certainly having a standard way to output console text is useful
early in linux for debugging. I'm not too sure about the others
though, in the simple case.

>
> > I am wondering if we can come up with a way to deterministically
> > specify how a system will boot and how to make it boot a different way
> > (i.e. with a different kernel, initrd, DT).
> >
> > Heinrich mentioned EFI variables as a way of selecting
> > kernel/initrd/DT. Then the problem becomes just a case of being able
> > to change those variables from Linux userspace. Is that right?
> >
> > We are talking about having a 'secure' part of EBBR, which allows for
> > secure boot. Should we have a 'defined boot' part of EBBR, that
> > defines how the kernel/DT/initrd are selected, based on EFI variables?
> >
> > Unfortunately I just don't know enough about all the different boot
> > flows used by the different distros. It seems like crazy town. Does
> > anyone have some pointers so I can do some study?
>
> A great way to get familiar with it is to play around with the UEFI code
> already in U-Boot with the UEFI Self Certification test suite. Building
> the SCT is straight forward, and there are some instructions for doing
> so here:
>
> https://github.com/glikely/edk2-test-manifest
>
> If you enable UEFI in U-Boot and copy the SCT to a USB drive, u-boot
> should be able to find and run the UEFI shell from the USB drive.
>
> There is also good documentation on the U-Boot implementation:
>
> https://github.com/u-boot/u-boot/blob/master/doc/uefi/uefi.rst

I have actually reviewed a lot of the code (and remember 5 years ago I
worked on the original lib/efi in U-Boot - see
doc/uefi/u-boot_on_efi.rst). But it is just hard to get my head around
all the pieces. It is the complexity of the bit between U-Boot and
Linux that I find challenging.

Thank you both for the pointers.

I think in general we are talking at cross purposes. I am looking for
how we can specify a simple verified boot, with or without EFI, so
that we actually create something that covers everything.
Distributions and particular cases may go to endless depths of
complexity, but if we want to incorporate the embedded case, then in
my view we need a simple option, with no more pieces, code, boot time
and complexity than is needed. It seems like the EFI protocol allows
this, so I imagine:

Simple EFI boot:

1. U-Boot starts*, selects and verifies config using UEFI variables,
loads image (linux, inittd, FPGA, DTs, etc.) verifying as it goes,
boots linux, passing in the images and providing EFI services as
specified by EBBR. OS updates use efibootmgr to select new kernels,
images, etc., as (to be) specified by EBBR

2. (degenerate case, where EFI is not used) U-Boot starts, selects and
verifies config using a proprietary mechanism, loads image (linux,
inittd, FPGA, DTs, etc.) verifying as it goes, boots linux, passing in
the images. Updates use a proprietary mechanism not specified by EBBR

Note that for platforms with separate firmware storage (e.g. SPI
flash), if the disk is wiped, or fails to to verify before or after
linux boots, then a recovery mode is needed to obtain a new disk
image. The firmware needs to be able to load, verify and write an
image to the disk so that the machine can continue to operate. Storing
firmware on the disk is not really viable. For other platforms,
presumably the disk is removable so the user can reflash it.

Complex EFI boot:

3. U-Boot (or anything else) starts, loads an EFI app (maybe grub or
something else) and provides EFI services as specified by EBBR. What
happens from there is distro-specific and not specified by EBBR.
Updates are handled by any means necessary and not specified by EBBR.

Regards,
Simon

* Of course there is ATF, SPL and other things which complicate this
piece. I think EBBR should specify these too.
_______________________________________________
boot-architecture mailing list
boot-architecture@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/boot-architecture

Reply via email to