summaryrefslogtreecommitdiff
path: root/lib/efi_loader
diff options
context:
space:
mode:
Diffstat (limited to 'lib/efi_loader')
-rw-r--r--lib/efi_loader/Kconfig3
-rw-r--r--lib/efi_loader/efi_bootbin.c87
-rw-r--r--lib/efi_loader/efi_boottime.c9
-rw-r--r--lib/efi_loader/efi_image_loader.c2
-rw-r--r--lib/efi_loader/efi_memory.c6
-rw-r--r--lib/efi_loader/efi_tcg2.c2
-rw-r--r--lib/efi_loader/elf_efi.ldsi74
7 files changed, 143 insertions, 40 deletions
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index c46ffe3a9d8..798dced475e 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -8,13 +8,14 @@ config EFI_LOADER
SYS_CPU = armv7 || \
SYS_CPU = armv8) || \
X86 || RISCV || SANDBOX)
+ # We have not fully removed the requirement for some block device
+ depends on BLK
# We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB
depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT
# We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB
depends on !EFI_STUB || !X86 || X86_64 || EFI_STUB_32BIT
depends on !EFI_APP
default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
- select BLK
select CHARSET
# We need to send DM events, dynamically, in the EFI block driver
select DM_EVENT
diff --git a/lib/efi_loader/efi_bootbin.c b/lib/efi_loader/efi_bootbin.c
index b677bbc3124..428991df88f 100644
--- a/lib/efi_loader/efi_bootbin.c
+++ b/lib/efi_loader/efi_bootbin.c
@@ -45,11 +45,63 @@ void efi_clear_bootdev(void)
}
/**
+ * calculate_paths() - Calculate the device and image patch from strings
+ *
+ * @dev: device, e.g. "MMC"
+ * @devnr: number of the device, e.g. "1:2"
+ * @path: path to file loaded
+ * @device_pathp: returns EFI device path
+ * @image_pathp: returns EFI image path
+ * Return: EFI_SUCCESS on success, else error code
+ */
+static efi_status_t calculate_paths(const char *dev, const char *devnr,
+ const char *path,
+ struct efi_device_path **device_pathp,
+ struct efi_device_path **image_pathp)
+{
+ struct efi_device_path *image, *device;
+ efi_status_t ret;
+
+#if IS_ENABLED(CONFIG_NETDEVICES)
+ if (!strcmp(dev, "Net") || !strcmp(dev, "Http")) {
+ ret = efi_net_set_dp(dev, devnr);
+ if (ret != EFI_SUCCESS)
+ return ret;
+ }
+#endif
+
+ ret = efi_dp_from_name(dev, devnr, path, &device, &image);
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ *device_pathp = device;
+ if (image) {
+ /* FIXME: image should not contain device */
+ struct efi_device_path *image_tmp = image;
+
+ efi_dp_split_file_path(image, &device, &image);
+ efi_free_pool(image_tmp);
+ }
+ *image_pathp = image;
+ log_debug("- boot device %pD\n", device);
+ if (image)
+ log_debug("- image %pD\n", image);
+
+ return EFI_SUCCESS;
+}
+
+/**
* efi_set_bootdev() - set boot device
*
* This function is called when a file is loaded, e.g. via the 'load' command.
* We use the path to this file to inform the UEFI binary about the boot device.
*
+ * For a valid image, it sets:
+ * - image_addr to the provided buffer
+ * - image_size to the provided buffer_size
+ * - bootefi_device_path to the EFI device-path
+ * - bootefi_image_path to the EFI image-path
+ *
* @dev: device, e.g. "MMC"
* @devnr: number of the device, e.g. "1:2"
* @path: path to file loaded
@@ -59,7 +111,6 @@ void efi_clear_bootdev(void)
void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
void *buffer, size_t buffer_size)
{
- struct efi_device_path *device, *image;
efi_status_t ret;
log_debug("dev=%s, devnr=%s, path=%s, buffer=%p, size=%zx\n", dev,
@@ -93,34 +144,12 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
image_addr = buffer;
image_size = buffer_size;
-#if IS_ENABLED(CONFIG_NETDEVICES)
- if (!strcmp(dev, "Net") || !strcmp(dev, "Http")) {
- ret = efi_net_set_dp(dev, devnr);
- if (ret != EFI_SUCCESS)
- goto error;
- }
-#endif
-
- ret = efi_dp_from_name(dev, devnr, path, &device, &image);
- if (ret != EFI_SUCCESS)
- goto error;
-
- bootefi_device_path = device;
- if (image) {
- /* FIXME: image should not contain device */
- struct efi_device_path *image_tmp = image;
-
- efi_dp_split_file_path(image, &device, &image);
- efi_free_pool(image_tmp);
+ ret = calculate_paths(dev, devnr, path, &bootefi_device_path,
+ &bootefi_image_path);
+ if (ret) {
+ log_debug("- efi_dp_from_name() failed, err=%lx\n", ret);
+ efi_clear_bootdev();
}
- bootefi_image_path = image;
- log_debug("- boot device %pD\n", device);
- if (image)
- log_debug("- image %pD\n", image);
- return;
-error:
- log_debug("- efi_dp_from_name() failed, err=%lx\n", ret);
- efi_clear_bootdev();
}
/**
@@ -130,7 +159,7 @@ error:
* @source_size: size of the UEFI image
* Return: status code
*/
-efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size)
+static efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size)
{
efi_handle_t mem_handle = NULL, handle;
struct efi_device_path *file_path = NULL;
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 080e7f78ae3..723a9b58691 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -3495,10 +3495,9 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
ret = efi_tcg2_measure_efi_app_exit();
- if (ret != EFI_SUCCESS) {
- log_warning("tcg2 measurement fails(0x%lx)\n",
- ret);
- }
+ if (ret != EFI_SUCCESS)
+ log_debug("tcg2 measurement fails (0x%lx)\n",
+ ret);
}
}
@@ -3733,7 +3732,7 @@ out:
*
* Return: status code
*/
-static efi_status_t EFIAPI efi_reinstall_protocol_interface(
+efi_status_t EFIAPI efi_reinstall_protocol_interface(
efi_handle_t handle, const efi_guid_t *protocol,
void *old_interface, void *new_interface)
{
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index bb58cf1badb..d002eb0c744 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -122,7 +122,7 @@ static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
return EFI_SUCCESS;
end = (const IMAGE_BASE_RELOCATION *)((const char *)rel + rel_size);
- while (rel < end && rel->SizeOfBlock) {
+ while (rel + 1 < end && rel->SizeOfBlock) {
const uint16_t *relocs = (const uint16_t *)(rel + 1);
i = (rel->SizeOfBlock - sizeof(*rel)) / sizeof(uint16_t);
while (i--) {
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index edd7da7d8c6..1212772471e 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -472,7 +472,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
switch (type) {
case EFI_ALLOCATE_ANY_PAGES:
/* Any page */
- addr = (u64)lmb_alloc_base_flags(len, EFI_PAGE_SIZE,
+ addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE,
LMB_ALLOC_ANYWHERE, flags);
if (!addr)
return EFI_OUT_OF_RESOURCES;
@@ -480,7 +480,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
case EFI_ALLOCATE_MAX_ADDRESS:
/* Max address */
addr = map_to_sysmem((void *)(uintptr_t)*memory);
- addr = (u64)lmb_alloc_base_flags(len, EFI_PAGE_SIZE, addr,
+ addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE, addr,
flags);
if (!addr)
return EFI_OUT_OF_RESOURCES;
@@ -490,7 +490,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
return EFI_NOT_FOUND;
addr = map_to_sysmem((void *)(uintptr_t)*memory);
- addr = (u64)lmb_alloc_addr_flags(addr, len, flags);
+ addr = (u64)lmb_alloc_addr(addr, len, flags);
if (!addr)
return EFI_NOT_FOUND;
break;
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 572c6b5bf63..a15c73162ee 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -791,7 +791,7 @@ static void tcg2_uninit(void)
efi_status_t ret;
ret = efi_install_configuration_table(&efi_guid_final_events, NULL);
- if (ret != EFI_SUCCESS)
+ if (ret != EFI_SUCCESS && ret != EFI_NOT_FOUND)
log_err("Failed to delete final events config table\n");
efi_free_pool(event_log.buffer);
diff --git a/lib/efi_loader/elf_efi.ldsi b/lib/efi_loader/elf_efi.ldsi
new file mode 100644
index 00000000000..190a88fb69e
--- /dev/null
+++ b/lib/efi_loader/elf_efi.ldsi
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * U-Boot EFI linker script include
+ *
+ * Modified from elf_aarch64_efi.lds in gnu-efi
+ */
+
+PHDRS
+{
+ data PT_LOAD FLAGS(3); /* SHF_WRITE | SHF_ALLOC */
+}
+
+ENTRY(_start)
+SECTIONS
+{
+ .text 0x0 : {
+ _text = .;
+ *(.text.head)
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ *(.srodata)
+ *(.rodata*)
+ . = ALIGN(16);
+ *(.dynamic);
+ . = ALIGN(512);
+ }
+ .rela.dyn : { *(.rela.dyn) }
+ .rela.plt : { *(.rela.plt) }
+ .rela.got : { *(.rela.got) }
+ .rela.data : { *(.rela.data) *(.rela.data*) }
+ . = ALIGN(4096);
+ _etext = .;
+ _text_size = . - _text;
+ .data : {
+ _data = .;
+ *(.sdata)
+ *(.data)
+ *(.data1)
+ *(.data.*)
+ *(.got.plt)
+ *(.got)
+
+ /*
+ * The EFI loader doesn't seem to like a .bss section, so we
+ * stick it all into .data:
+ */
+ . = ALIGN(16);
+ _bss = .;
+ *(.sbss)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ . = ALIGN(512);
+ _bss_end = .;
+ _edata = .;
+ } :data
+ _data_size = _edata - _data;
+
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ .note.gnu.build-id : { *(.note.gnu.build-id) }
+ /DISCARD/ : {
+ *(.rel.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}