Am 1. Oktober 2020 23:19:08 MESZ schrieb Ard Biesheuvel <a...@kernel.org>:
>On Thu, 1 Oct 2020 at 22:30, Simon Glass <s...@chromium.org> wrote:
>>
>> Hi Grant,
>>
>> [who is 'nd'?]
>>
>
>That would be our bot who kindly omits of the obnoxious email footer
>on outgoing email if cc'ed.
>
>> 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.
>>
>
>Another advantage of EFI boot is that it allows us to avoid putting
>Linux specific knowledge into the bootloader, which is typically
>different for every architecture:
>- On x86, the location of the initrd and the commandline are passed
>via the boot_params struct, and where these may be loaded in memory is
>different between i686 and x86_64, differs between Linux versions, and
>is also dependent on whether the kernel is KASLR capable or not. Where
>the boot_params struct itself may be loaded in memory also varies.
>- on ARM and arm64 the location of the initrd and the contents of the
>command line are passed via DT - where the initrd may be loaded is
>arch specific, and the DT needs to be in lowmem (but the size of
>lowmem depends on your kernel config)
>- on ARM, the zImage must be placed within 128 MB of the start of DRAM
>- on arm64, the kernel Image must be aligned to 2 MB in memory, unless
>it is a KASLR kernel, in which case 64 KB is sufficient
>- KASLR seeds are passed in different ways
>- RISC-V yay!
>- etc etc
>
>We have managed to move all this complex policy into the EFI stub for
>Linux, which only needs the EFI APIs, which are rigorously specified
>and documented, and vary very little between architectures. We have
>defined an arch-agnostic initrd EFI protocol on the Linux side, which
>the bootloader can expose (and which is already implemented by uboot),
>and provides a natural hook for attestation/measurement.
>
>As a result, we have defined a generic EFI based platform, where
>secure boot and measured boot, and perhaps even firmware update can be
>implemented according to an industry spec, and the resulting code
>should deviate very little (if at all) between all these
>architectures.

The architecture specific quirks that I am aware of are:

* State of caches and MMU
* Boot hart ID in device tree for RISC-V
* Exception level (EL2, S-mode)
* Restrictions on the memory map
* Calling conventions
* PE-COFF file format depending on 32/64 bit

Best regards

Heinrich

_______________________________________________
boot-architecture mailing list
boot-architecture@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/boot-architecture

Reply via email to