[PATCH v5 0/8] efi: implement generic compressed boot support
Jeremy Linton
jeremy.linton at arm.com
Sun Sep 18 19:22:22 PDT 2022
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 at 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 at HansenPartnership.com>
> Cc: Matthew Garrett <mjg59 at srcf.ucam.org>
> Cc: Peter Jones <pjones at redhat.com>
> Cc: Ilias Apalodimas <ilias.apalodimas at linaro.org>
> Cc: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
> Cc: AKASHI Takahiro <takahiro.akashi at linaro.org>
> Cc: Palmer Dabbelt <palmer at dabbelt.com>
> Cc: Atish Patra <atishp at atishpatra.org>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Huacai Chen <chenhuacai at loongson.cn>
> Cc: Xi Ruoyao <xry111 at xry111.site>
> Cc: Lennart Poettering <lennart at poettering.net>
> Cc: Jeremy Linton <jeremy.linton at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at 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
>
More information about the linux-arm-kernel
mailing list