On Tue, 9 Aug 2022 at 11:03, Heinrich Schuchardt <heinrich.schuchardt@xxxxxxxxxxxxx> wrote: > > On 8/9/22 10:46, Ard Biesheuvel wrote: > > On Tue, 9 Aug 2022 at 10:38, Heinrich Schuchardt > > <heinrich.schuchardt@xxxxxxxxxxxxx> wrote: > >> > >> On 8/9/22 10:09, Ard Biesheuvel wrote: > >>> Relatively modern architectures such as arm64 or RISC-V don't implement > >>> a self-decompressing kernel, and leave it up to the bootloader to > >>> decompress the compressed image before executing it. For bare metal > >>> boot, this policy makes sense, as a self-decompressing image essentially > >>> duplicates a lot of fiddly preparation work to create a 1:1 mapping and > >>> set up the C runtime, and to discover or infer where DRAM lives from > >>> device trees or other firmware tables. > >>> > >>> For EFI boot, the situation is a bit different: the EFI entrypoint is > >>> called with a 1:1 cached mapping covering all of DRAM already active, > >>> and with a stack, a heap, a memory map and boot services to load and > >>> start images. This means it is rather trivial to implement a > >>> self-decompressing wrapper for EFI boot in a generic manner, and reuse > >>> it across architectures that implement EFI boot. > >>> > >>> The only slight downside is that when UEFI secure boot is enabled, the > >>> generic LoadImage/StartImage only allow signed images to be loaded and > >>> started, and we prefer to avoid the need to sign both the inner and > >>> outer PE/COFF images. This series adopts the EFI shim approach, i.e., to > >>> override an internal UEFI/PI protocol that is used by the image loader, > >>> to allow the inner image to be booted after decompression. This has been > >> > >> We should avoid requiring anything that is not in the UEFI > >> specification. If you have any additional requirements, please, create a > >> change request for the UEFI specification. > >> > > > > As I have explained numerous times before, the EFI spec was intended > > to be extensible (hence the 'E'). The ACPI, SMBIOS and TCG specs all > > augment the EFI specification by defining protocols, GUIDs and other > > things that are only relevant in a EFI context, but none of those are > > covered by the EFI spec itself. > > > >> Overriding the services of the system table is dangerous and should be > >> avoided. > >> > > > > Agreed. But this is not what is happening here. > > > >> There is no need for two UEFI binaries one inside the other and we > >> should avoid such overengineering. > >> > > > > I disagree. Using an EFI app to encapsulate another one is the only > > generic way to go about this, as far as I can tell. > > Please, elaborate why the inner compressed binary needs to be UEFI to > boot into Linux while currently we don't need a an uncompressed inner > UEFI binary. > If the inner binary is not EFI / PE/COFF, there is no generic way to boot it. Every architecture has its own rules of how this needs to be implemented. > > > >> Today we append an uncompressed kernel to the EFI stub. The stub > >> relocates it, sets up the memory map and calls it entry point. > >> > > > > Not exactly. On arm64 as well as RISC-V, the EFI stub and the kernel > > proper are essentially the same executable image. > > Currently on ARM and RISC-V you have a file with two entry points: > > * EFI stub > * legacy entry point > > The EFI stub calls the legacy entry point. In the EFI case some part of > the EFI stub lives on at runtime. The same pointers passed to the legacy > entry point could also be passed to a decompressed legacy kernel. > Nit: no part of the EFI stub lives on at runtime, but that is beside the point. You are right that the EFI stub could be logically disjoint from the payload, and so it could theoretically decompress its payload before starting it. > The EFI stub and the kernel should be completely separate binaries. Then > you just need the cp command to join them. > It is not that simple, unfortunately. The EFI stub on arm64 and RISC-V refers to many ELF symbols directly, and so splitting those images requires some intrusive build system changes. > > > >> Just add decompressor code to the EFI stub and instead of appending an > >> uncompressed kernel append a compressed one. Then sign a binary > >> consisting of the EFI stub and the compressed kernel. > >> > > > > Yes, this would be a cleaner approach, although it would require more > > re-engineering of the EFI stub, in particular, it would require > > cloning more code, and adding additional build and link steps. > > If this is the cleanest approach, we should go for it. > That is a fair point. Unfortunately, it will no longer be generic, and each architecture will have to implement this individually.