On 2.3.2020 1.05, Arvind Sankar wrote: > When booted via PE loader, define image_offset to hold the offset of > startup_32 from the start of the PE image, and use it as the start of > the decompression buffer. > > Signed-off-by: Arvind Sankar > --- > arch/x86/boot/compressed/head_32.S | 17 +++++++++++ > arch/x86/boot/compressed/head_64.S | 38 +++++++++++++++++++++++-- > drivers/firmware/efi/libstub/x86-stub.c | 12 ++++++-- > 3 files changed, 61 insertions(+), 6 deletions(-) ... > --- a/drivers/firmware/efi/libstub/x86-stub.c > +++ b/drivers/firmware/efi/libstub/x86-stub.c > @@ -19,6 +19,7 @@ > > static efi_system_table_t *sys_table; > extern const bool efi_is64; > +extern u32 image_offset; > > __pure efi_system_table_t *efi_system_table(void) > { > @@ -364,6 +365,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, > struct boot_params *boot_params; > struct setup_header *hdr; > efi_loaded_image_t *image; > + void *image_base; > efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; > int options_size = 0; > efi_status_t status; > @@ -384,7 +386,10 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, > efi_exit(handle, status); > } > > - hdr = &((struct boot_params *)efi_table_attr(image, image_base))->hdr; > + image_base = efi_table_attr(image, image_base); > + image_offset = (void *)startup_32 - image_base; startup_32 == 0, so maybe something like leaq startup_32(%rip) - image_base should be used ? > + > + hdr = &((struct boot_params *)image_base)->hdr; > above4g = hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G; > > status = efi_allocate_pages(0x4000, (unsigned long *)&boot_params, > @@ -399,7 +404,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, > hdr = &boot_params->hdr; > > /* Copy the second sector to boot_params */ > - memcpy(&hdr->jump, efi_table_attr(image, image_base) + 512, 512); > + memcpy(&hdr->jump, image_base + 512, 512); > > /* > * Fill out some of the header fields ourselves because the > @@ -726,7 +731,7 @@ unsigned long efi_main(efi_handle_t handle, > * If the kernel isn't already loaded at the preferred load > * address, relocate it. > */ > - if (bzimage_addr != hdr->pref_address) { > + if (bzimage_addr - image_offset != hdr->pref_address) { > status = efi_relocate_kernel(&bzimage_addr, > hdr->init_size, hdr->init_size, > hdr->pref_address, > @@ -736,6 +741,7 @@ unsigned long efi_main(efi_handle_t handle, > efi_printk("efi_relocate_kernel() failed!\n"); > goto fail; > } > + image_offset = 0; > } > > /*