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