Message ID | 20220910081152.2238369-1-ardb@kernel.org |
---|---|
Headers | show |
Series | efi: implement generic compressed boot support | expand |
Hi, With the BSS "fix" in grub for fedora/rhel, this is now working fine for both systemd-boot and normal grub2, as well as booting directly from the UEFI shell. Given both the magic number and the bss fix were merged at the same time I don't think anyone should ever see the bad bss message, at least not on the above distro's. I've largely been testing this on the PFTF/RPi4, and in a libvirt qemu/kvm env with/without ksan/etc on a mostly fedora configured kernel. Hooking this up to kinstall makes sense and works, although i'm not a big fan. So, its looking good. All thumbs up here :) Tested-by: Jeremy Linton <jeremy.linton@arm.com> On 9/10/22 03:11, 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 would prefer to avoid the need to sign both the inner > and outer PE/COFF images. > > However, the only truly generic and portable way to achieve this is to > rely on LoadImage/StartImage as the EFI spec defines them, and avoid > making assumptions about how things might work under the hood, and how > we might circumvent that. This includes just loading the image into > memory and jumping to the PE entry point: in the context of secure boot, > measured boot and other hardening measures the firmware may take (such > as disallowing mappings that are both writable and executable), using > the firmware's image loading API is the only maintainable choice. > > For this reason, this version of the series includes support for signing > the images using sbsign, if the signing key and cert are specified in > Kconfig. > > The code is wired up for arm64, LoongArch and RISC-V. The latter was > build tested only. > > Changes since v4: > - make CONFIG_EFI_ZBOOT user selectable again, and turn it on by default > only for LoongArch > - set KBUILD_IMAGE to vmlinuz.efi if CONFIG_EFI_ZBOOT=y, so that make > targets such as zinstall and bindeb-pkg do the right thing > - throw an error is BSS was not cleared by the loader - this is needed > to detect broken distro implementations of LoadImage in shim and grub > - add vmlinuz.* to .gitignore on the various architectures > - switch back to defining uncompressed_size as 'extern __aligned(1)' so > that the compiler will perform the unaligned access as appropriate on > the architecture in question - this requires the latest binutils on > LoongArch [0] > > Changes since v3: > - add support for XZ and ZSTD compression > - deal with exit data returned by StartImage() > - use LoadFile2 based image loading instead of passing the raw buffer - > this way, the provenance of the data is more visible, allowing us, > for instance, to deal with initrd= on arm64 transparently (this means > that systemd-boot on arm64 will work unmodified provided that the > [deprecated] command line initrd loader is enabled in the kernel > build) > - include LoongArch support > - rename compressed image to vmlinuz.efi on all architectures > > Changes since v2: > - drop some of the refactoring work to make efi_printk() available in > the decompressor, and just use fixed strings instead; > - provide memcpy/memmove/memset based on the UEFI boot services, instead > of having to specify for each architecture how to wire these up; > - drop PI/DXE based signature check circumvention, and just sign the > inner image instead, if needed; > - add a header to the zimage binary that identifies it as a EFI zboot > image, and describes the compression algorithm and where the payload > lives in the image - this might be used by non-EFI loaders to locate > and decompress the bare metal image, given that the EFI zboot one is > not a hybrid like the one it encapsulates. > > [0] https://sourceware.org/pipermail/binutils/2022-September/122713.html > > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> > Cc: Matthew Garrett <mjg59@srcf.ucam.org> > Cc: Peter Jones <pjones@redhat.com> > Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org> > Cc: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> > Cc: AKASHI Takahiro <takahiro.akashi@linaro.org> > Cc: Palmer Dabbelt <palmer@dabbelt.com> > Cc: Atish Patra <atishp@atishpatra.org> > Cc: Arnd Bergmann <arnd@arndb.de> > Cc: Huacai Chen <chenhuacai@loongson.cn> > Cc: Xi Ruoyao <xry111@xry111.site> > Cc: Lennart Poettering <lennart@poettering.net> > Cc: Jeremy Linton <jeremy.linton@arm.com> > Cc: Will Deacon <will@kernel.org> > Cc: Catalin Marinas <catalin.marinas@arm.com> > > Ard Biesheuvel (8): > efi: name the ARCH-stub.c files uniformly > efi/libstub: add some missing EFI prototypes > efi/libstub: use EFI provided memcpy/memset routines > efi/libstub: move efi_system_table global var into separate object > efi/libstub: implement generic EFI zboot > arm64: efi: enable generic EFI compressed boot > riscv: efi: enable generic EFI compressed boot > loongarch: efi: enable generic EFI compressed boot > > arch/arm64/Makefile | 9 +- > arch/arm64/boot/.gitignore | 1 + > arch/arm64/boot/Makefile | 6 + > arch/arm64/kernel/image-vars.h | 13 - > arch/loongarch/Kconfig | 1 + > arch/loongarch/Makefile | 4 +- > arch/loongarch/boot/.gitignore | 1 + > arch/loongarch/boot/Makefile | 6 + > arch/loongarch/kernel/image-vars.h | 3 - > arch/riscv/Makefile | 6 +- > arch/riscv/boot/.gitignore | 1 + > arch/riscv/boot/Makefile | 6 + > arch/riscv/kernel/image-vars.h | 9 - > drivers/firmware/efi/Kconfig | 38 +++ > drivers/firmware/efi/libstub/Makefile | 21 +- > drivers/firmware/efi/libstub/Makefile.zboot | 70 +++++ > drivers/firmware/efi/libstub/{arm32-stub.c => arm-stub.c} | 0 > drivers/firmware/efi/libstub/efi-stub.c | 2 - > drivers/firmware/efi/libstub/efistub.h | 35 ++- > drivers/firmware/efi/libstub/file.c | 17 ++ > drivers/firmware/efi/libstub/intrinsics.c | 30 ++ > drivers/firmware/efi/libstub/systable.c | 8 + > drivers/firmware/efi/libstub/zboot-header.S | 143 ++++++++++ > drivers/firmware/efi/libstub/zboot.c | 296 ++++++++++++++++++++ > drivers/firmware/efi/libstub/zboot.lds | 43 +++ > include/linux/efi.h | 13 + > 26 files changed, 732 insertions(+), 50 deletions(-) > create mode 100644 drivers/firmware/efi/libstub/Makefile.zboot > rename drivers/firmware/efi/libstub/{arm32-stub.c => arm-stub.c} (100%) > create mode 100644 drivers/firmware/efi/libstub/intrinsics.c > create mode 100644 drivers/firmware/efi/libstub/systable.c > create mode 100644 drivers/firmware/efi/libstub/zboot-header.S > create mode 100644 drivers/firmware/efi/libstub/zboot.c > create mode 100644 drivers/firmware/efi/libstub/zboot.lds >