On Thu, Jul 18, 2024 at 4:58 PM Pingfan Liu <piliu@xxxxxxxxxx> wrote: > > > *** Background *** > > As more PE format kernel images are introduced, it post challenge to kexec to > cope with the new format. > > In my attempt to add support for arm64 zboot image in the kernel [1], > Ard suggested using an emulator to tackle this issue. Last year, when > Jan tried to introduce UKI support in the kernel [2], Ard mentioned the > emulator approach again [3] > > After discussion, Ard's approach seems to be a more promising solution > to handle PE format kernels once and for all. This series follows that > approach and implements an emulator to emulate EFI boot time services, > allowing the efistub kernel to self-extract and boot. > > > > *** Overview of implement *** > The whole model consits of three parts: > > -1. The emulator > It is a self-relocatable PIC code, which is finally linked into kernel, but not > export any internal symbol to kernel. It mainly contains: a PE file parser, > which loads PE format kernel, a group of functions to emulate efi boot service. > > -2. inside kernel, PE-format loader > Its main task is to set up two extra kexec_segment, one for emulator, the other > for passing information from the first kernel to emulator. > > -3. set up identity mapping only for the memory used by the emulator. > Here it relies on kimage_alloc_control_pages() to get pages, which will not > stamped during the process of kexec relocate (cp from src to dst). And since the > mapping only covers a small range of memory, it cost small amount memory. > > > *** To do *** > > Currently, it only works on arm64 _zboot_ image on arm64 virt machine. For > arm64 UKI, I have not completed it. But it should be easy to archieve by Not familiar with UKI, after going through the systemd/src/boot/efi/initrd.c, I guess systemd-stub plays as a EFI application, it calls initrd_register() to install the initrd information. After systemd-stub transmits the control to the efistub linux kernel, the efistub will get the initrd. So all should spin around the EFI_LOAD_FILE2_PROTOCOL. Am I right? Thanks, Pingfan > implementing EFI_LOAD_FILE2_PROTOCOL.LoadFile(). And with a slightly > improvement, it would work on x86. > > Besides that, as POC, I skip four functions in efistub: setup_graphics(), > efi_random_get_seed() and efi_enable_reset_attack_mitigation(), > efi_retrieve_eventlog(). Hence skipping the corresponding boot services. > > Also, this series does not implement a memory allocator, which I plan to > implement with the help of bitmap. > > About console, currently it hard code for arm64 virt machine, later it should > extract the information through ACPI table. > > [1]: https://lore.kernel.org/linux-arm-kernel/ZBvKSis+dfnqa+Vz@xxxxxxxxxxxxxxxxxxxxxxxxxx/T/#m42abb0ad3c10126b8b3bfae8a596deb707d6f76e > [2]: https://lore.kernel.org/lkml/20230918173607.421d2616@rotkaeppchen/T/ > [3]: https://lore.kernel.org/lkml/20230918173607.421d2616@rotkaeppchen/T/#mc60aa591cb7616ceb39e1c98f352383f9ba6e985 > > > Cc: Ard Biesheuvel <ardb@xxxxxxxxxx> > Cc: Jan Hendrik Farr <kernel@xxxxxxxx> > Cc: Philipp Rudo <prudo@xxxxxxxxxx> > Cc: Lennart Poettering <mzxreary@xxxxxxxxxxx> > Cc: Jarkko Sakkinen <jarkko@xxxxxxxxxx> > Cc: Baoquan He <bhe@xxxxxxxxxx> > Cc: Dave Young <dyoung@xxxxxxxxxx> > Cc: Mark Rutland <mark.rutland@xxxxxxx> > Cc: Will Deacon <will@xxxxxxxxxx> > Cc: Catalin Marinas <catalin.marinas@xxxxxxx> > To: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx > To: kexec@xxxxxxxxxxxxxxxxxxx > To: linux-efi@xxxxxxxxxxxxxxx > > Pingfan Liu (7): > efi/libstub: Ask efi_random_alloc() to skip unusable memory > debug/libstub: cheats to step around some boot service > efi/emulator: Initial rountines to emulate EFI boot time service > efi/emulator: Turn on mmu for arm64 > arm64: mm: Change to prototype of > arm64: kexec: Prepare page table for emulator > kexec: Introduce kexec_pe_image to parse and load PE file > > arch/arm64/include/asm/kexec.h | 3 + > arch/arm64/include/asm/mmu.h | 6 + > arch/arm64/kernel/Makefile | 2 +- > arch/arm64/kernel/kexec_image.c | 1 + > arch/arm64/kernel/kexec_pe_image.c | 519 ++++++++++++++++++ > arch/arm64/kernel/machine_kexec.c | 90 ++- > arch/arm64/kernel/machine_kexec_file.c | 1 + > arch/arm64/mm/mmu.c | 67 ++- > drivers/firmware/efi/Makefile | 1 + > drivers/firmware/efi/efi_emulator/Makefile | 98 ++++ > .../firmware/efi/efi_emulator/amba-pl011.c | 80 +++ > .../efi_emulator/arm64_emulator_service.lds | 45 ++ > .../firmware/efi/efi_emulator/arm64_proc.S | 172 ++++++ > .../firmware/efi/efi_emulator/config_table.c | 23 + > drivers/firmware/efi/efi_emulator/core.c | 211 +++++++ > drivers/firmware/efi/efi_emulator/earlycon.h | 19 + > .../firmware/efi/efi_emulator/efi_emulator.S | 12 + > drivers/firmware/efi/efi_emulator/emulator.h | 66 +++ > drivers/firmware/efi/efi_emulator/entry.c | 64 +++ > drivers/firmware/efi/efi_emulator/head.S | 10 + > drivers/firmware/efi/efi_emulator/initrd.c | 15 + > drivers/firmware/efi/efi_emulator/lib.c | 73 +++ > drivers/firmware/efi/efi_emulator/memory.c | 27 + > .../firmware/efi/efi_emulator/memory_api.c | 73 +++ > drivers/firmware/efi/efi_emulator/misc.c | 76 +++ > drivers/firmware/efi/efi_emulator/pe_loader.c | 124 +++++ > drivers/firmware/efi/efi_emulator/printf.c | 389 +++++++++++++ > .../efi/efi_emulator/runtime_service.c | 28 + > .../firmware/efi/libstub/efi-stub-helper.c | 3 + > drivers/firmware/efi/libstub/efi-stub.c | 2 + > drivers/firmware/efi/libstub/random.c | 2 + > drivers/firmware/efi/libstub/randomalloc.c | 5 + > drivers/firmware/efi/libstub/tpm.c | 4 + > include/linux/efi_emulator.h | 46 ++ > include/linux/kexec.h | 5 + > 35 files changed, 2327 insertions(+), 35 deletions(-) > create mode 100644 arch/arm64/kernel/kexec_pe_image.c > create mode 100644 drivers/firmware/efi/efi_emulator/Makefile > create mode 100644 drivers/firmware/efi/efi_emulator/amba-pl011.c > create mode 100644 drivers/firmware/efi/efi_emulator/arm64_emulator_service.lds > create mode 100644 drivers/firmware/efi/efi_emulator/arm64_proc.S > create mode 100644 drivers/firmware/efi/efi_emulator/config_table.c > create mode 100644 drivers/firmware/efi/efi_emulator/core.c > create mode 100644 drivers/firmware/efi/efi_emulator/earlycon.h > create mode 100644 drivers/firmware/efi/efi_emulator/efi_emulator.S > create mode 100644 drivers/firmware/efi/efi_emulator/emulator.h > create mode 100644 drivers/firmware/efi/efi_emulator/entry.c > create mode 100644 drivers/firmware/efi/efi_emulator/head.S > create mode 100644 drivers/firmware/efi/efi_emulator/initrd.c > create mode 100644 drivers/firmware/efi/efi_emulator/lib.c > create mode 100644 drivers/firmware/efi/efi_emulator/memory.c > create mode 100644 drivers/firmware/efi/efi_emulator/memory_api.c > create mode 100644 drivers/firmware/efi/efi_emulator/misc.c > create mode 100644 drivers/firmware/efi/efi_emulator/pe_loader.c > create mode 100644 drivers/firmware/efi/efi_emulator/printf.c > create mode 100644 drivers/firmware/efi/efi_emulator/runtime_service.c > create mode 100644 include/linux/efi_emulator.h > > -- > 2.41.0 >