mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
efi: libstub: Factor out EFI stub entrypoint into separate file
In preparation for allowing the EFI zboot decompressor to reuse most of the EFI stub machinery, factor out the actual EFI PE/COFF entrypoint into a separate file. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
parent
da8dd0c75b
commit
42c8ea3dca
@ -83,7 +83,7 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
|
||||
lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \
|
||||
screen_info.o
|
||||
screen_info.o efi-stub-entry.o
|
||||
|
||||
lib-$(CONFIG_ARM) += arm32-stub.o
|
||||
lib-$(CONFIG_ARM64) += arm64-stub.o arm64-entry.o
|
||||
|
65
drivers/firmware/efi/libstub/efi-stub-entry.c
Normal file
65
drivers/firmware/efi/libstub/efi-stub-entry.c
Normal file
@ -0,0 +1,65 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
#include <linux/efi.h>
|
||||
#include <asm/efi.h>
|
||||
|
||||
#include "efistub.h"
|
||||
|
||||
/*
|
||||
* EFI entry point for the generic EFI stub used by ARM, arm64, RISC-V and
|
||||
* LoongArch. This is the entrypoint that is described in the PE/COFF header
|
||||
* of the core kernel.
|
||||
*/
|
||||
efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
|
||||
efi_system_table_t *systab)
|
||||
{
|
||||
efi_loaded_image_t *image;
|
||||
efi_status_t status;
|
||||
unsigned long image_addr;
|
||||
unsigned long image_size = 0;
|
||||
/* addr/point and size pairs for memory management*/
|
||||
char *cmdline_ptr = NULL;
|
||||
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
|
||||
unsigned long reserve_addr = 0;
|
||||
unsigned long reserve_size = 0;
|
||||
|
||||
WRITE_ONCE(efi_system_table, systab);
|
||||
|
||||
/* Check if we were booted by the EFI firmware */
|
||||
if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
/*
|
||||
* Get a handle to the loaded image protocol. This is used to get
|
||||
* information about the running image, such as size and the command
|
||||
* line.
|
||||
*/
|
||||
status = efi_bs_call(handle_protocol, handle, &loaded_image_proto,
|
||||
(void *)&image);
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_err("Failed to get loaded image protocol\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = efi_handle_cmdline(image, &cmdline_ptr);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
efi_info("Booting Linux Kernel...\n");
|
||||
|
||||
status = handle_kernel_image(&image_addr, &image_size,
|
||||
&reserve_addr,
|
||||
&reserve_size,
|
||||
image, handle);
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_err("Failed to relocate kernel\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = efi_stub_common(handle, image, image_addr, cmdline_ptr);
|
||||
|
||||
efi_free(image_size, image_addr);
|
||||
efi_free(reserve_size, reserve_addr);
|
||||
|
||||
return status;
|
||||
}
|
@ -115,61 +115,21 @@ static u32 get_supported_rt_services(void)
|
||||
return supported;
|
||||
}
|
||||
|
||||
/*
|
||||
* EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint
|
||||
* that is described in the PE/COFF header. Most of the code is the same
|
||||
* for both archictectures, with the arch-specific code provided in the
|
||||
* handle_kernel_image() function.
|
||||
*/
|
||||
efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
|
||||
efi_system_table_t *sys_table_arg)
|
||||
efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr)
|
||||
{
|
||||
efi_loaded_image_t *image;
|
||||
efi_status_t status;
|
||||
unsigned long image_addr;
|
||||
unsigned long image_size = 0;
|
||||
/* addr/point and size pairs for memory management*/
|
||||
char *cmdline_ptr = NULL;
|
||||
int cmdline_size = 0;
|
||||
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
|
||||
unsigned long reserve_addr = 0;
|
||||
unsigned long reserve_size = 0;
|
||||
struct screen_info *si;
|
||||
|
||||
efi_system_table = sys_table_arg;
|
||||
|
||||
/* Check if we were booted by the EFI firmware */
|
||||
if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) {
|
||||
status = EFI_INVALID_PARAMETER;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
status = check_platform_features();
|
||||
if (status != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Get a handle to the loaded image protocol. This is used to get
|
||||
* information about the running image, such as size and the command
|
||||
* line.
|
||||
*/
|
||||
status = efi_bs_call(handle_protocol, handle, &loaded_image_proto,
|
||||
(void *)&image);
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_err("Failed to get loaded image protocol\n");
|
||||
goto fail;
|
||||
}
|
||||
efi_status_t status;
|
||||
char *cmdline;
|
||||
|
||||
/*
|
||||
* Get the command line from EFI, using the LOADED_IMAGE
|
||||
* protocol. We are going to copy the command line into the
|
||||
* device tree, so this can be allocated anywhere.
|
||||
*/
|
||||
cmdline_ptr = efi_convert_cmdline(image, &cmdline_size);
|
||||
if (!cmdline_ptr) {
|
||||
cmdline = efi_convert_cmdline(image, &cmdline_size);
|
||||
if (!cmdline) {
|
||||
efi_err("getting command line via LOADED_IMAGE_PROTOCOL\n");
|
||||
status = EFI_OUT_OF_RESOURCES;
|
||||
goto fail;
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
|
||||
@ -183,26 +143,35 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
|
||||
}
|
||||
|
||||
if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && cmdline_size > 0) {
|
||||
status = efi_parse_options(cmdline_ptr);
|
||||
status = efi_parse_options(cmdline);
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_err("Failed to parse options\n");
|
||||
goto fail_free_cmdline;
|
||||
}
|
||||
}
|
||||
|
||||
efi_info("Booting Linux Kernel...\n");
|
||||
*cmdline_ptr = cmdline;
|
||||
return EFI_SUCCESS;
|
||||
|
||||
fail_free_cmdline:
|
||||
efi_bs_call(free_pool, cmdline_ptr);
|
||||
return status;
|
||||
}
|
||||
|
||||
efi_status_t efi_stub_common(efi_handle_t handle,
|
||||
efi_loaded_image_t *image,
|
||||
unsigned long image_addr,
|
||||
char *cmdline_ptr)
|
||||
{
|
||||
struct screen_info *si;
|
||||
efi_status_t status;
|
||||
|
||||
status = check_platform_features();
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
si = setup_graphics();
|
||||
|
||||
status = handle_kernel_image(&image_addr, &image_size,
|
||||
&reserve_addr,
|
||||
&reserve_size,
|
||||
image, handle);
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_err("Failed to relocate kernel\n");
|
||||
goto fail_free_screeninfo;
|
||||
}
|
||||
|
||||
efi_retrieve_tpm2_eventlog();
|
||||
|
||||
/* Ask the firmware to clear memory on unclean shutdown */
|
||||
@ -221,13 +190,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
|
||||
|
||||
status = efi_boot_kernel(handle, image, image_addr, cmdline_ptr);
|
||||
|
||||
efi_free(image_size, image_addr);
|
||||
efi_free(reserve_size, reserve_addr);
|
||||
fail_free_screeninfo:
|
||||
free_screen_info(si);
|
||||
fail_free_cmdline:
|
||||
efi_bs_call(free_pool, cmdline_ptr);
|
||||
fail:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -958,6 +958,14 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
|
||||
efi_loaded_image_t *image,
|
||||
efi_handle_t image_handle);
|
||||
|
||||
/* shared entrypoint between the normal stub and the zboot stub */
|
||||
efi_status_t efi_stub_common(efi_handle_t handle,
|
||||
efi_loaded_image_t *image,
|
||||
unsigned long image_addr,
|
||||
char *cmdline_ptr);
|
||||
|
||||
efi_status_t efi_handle_cmdline(efi_loaded_image_t *image, char **cmdline_ptr);
|
||||
|
||||
asmlinkage void __noreturn efi_enter_kernel(unsigned long entrypoint,
|
||||
unsigned long fdt_addr,
|
||||
unsigned long fdt_size);
|
||||
|
Loading…
Reference in New Issue
Block a user