From cab6f06c14a2a059621ef51b241a0089beb48cfd Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 30 Oct 2019 20:13:24 +0100 Subject: efi_loader: fix efi_dp_from_name() Correctly check the return value of efi_dp_from_file(). If we can determine device path for the file, should not depend on the device path for the device being requested. Provide a function description for efi_dp_from_name(). Reported-by: Coverity CID 273159, CID 273158 Fixes: 08c51fff30cc ("efi_loader: device_path: check against file path length") Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_device_path.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index ac5e6f7e14f..17a0c5bb450 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -1032,6 +1032,16 @@ out: return EFI_SUCCESS; } +/** + * efi_dp_from_name() - convert U-Boot device and file path to device path + * + * @dev: U-Boot device, e.g. 'mmc' + * @devnr: U-Boot device number, e.g. 1 for 'mmc:1' + * @path: file path relative to U-Boot device, may be NULL + * @device: pointer to receive device path of the device + * @file: pointer to receive device path for the file + * Return: status code + */ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, const char *path, struct efi_device_path **device, @@ -1071,10 +1081,9 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, s = filename; while ((s = strchr(s, '/'))) *s++ = '\\'; - *file = efi_dp_from_file(((!is_net && device) ? desc : NULL), - part, filename); + *file = efi_dp_from_file(is_net ? NULL : desc, part, filename); - if (!file) + if (!*file) return EFI_INVALID_PARAMETER; return EFI_SUCCESS; -- cgit v1.3.1 From 89cb6a5dd6d44dc7293845d63ee29fe6b7cd1d09 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Mon, 7 Oct 2019 14:59:39 +0900 Subject: efi_loader: disk: install file system protocol to a whole disk Currently, a whole disk without any partitions is not associated with EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. So even if it houses some file system, there is a chance that we may not be able to access it, particularly, when accesses are to be attempted after searching that protocol against a device handle. With this patch, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL is installed to such a disk if part_get_info() shows there is no partition table installed on it. Signed-off-by: AKASHI Takahiro Only if no partition table exists, check for a file system on disk level. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_disk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 861fcaf3747..ed7fb3f7d33 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -337,7 +337,9 @@ static efi_status_t efi_disk_add_dev( diskobj->dp); if (ret != EFI_SUCCESS) return ret; - if (part >= 1 && efi_fs_exists(desc, part)) { + /* partitions or whole disk without partitions */ + if ((part || desc->part_type == PART_TYPE_UNKNOWN) && + efi_fs_exists(desc, part)) { diskobj->volume = efi_simple_file_system(desc, part, diskobj->dp); ret = efi_add_protocol(&diskobj->header, -- cgit v1.3.1 From 7264e21fdead677687934eecda6ac98f37851acf Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 8 Nov 2019 20:42:53 +0100 Subject: efi_loader: call add_u_boot_and_runtime() on sandbox On the sandbox we should mark the stack area as EFI runtime memory like we do on any other architecture. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_memory.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lib/efi_loader') diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 83cbc9154f3..d46001f608b 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -738,8 +738,10 @@ static void add_u_boot_and_runtime(void) unsigned long uboot_stack_size = 16 * 1024 * 1024; /* Add U-Boot */ - uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK; - uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT; + uboot_start = ((uintptr_t)map_sysmem(gd->start_addr_sp, 0) - + uboot_stack_size) & ~EFI_PAGE_MASK; + uboot_pages = ((uintptr_t)map_sysmem(gd->ram_top - 1, 0) - + uboot_start + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT; efi_add_memory_map(uboot_start, uboot_pages, EFI_LOADER_DATA, false); #if defined(__aarch64__) @@ -767,8 +769,7 @@ int efi_memory_init(void) { efi_add_known_memory(); - if (!IS_ENABLED(CONFIG_SANDBOX)) - add_u_boot_and_runtime(); + add_u_boot_and_runtime(); #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER /* Request a 32bit 64MB bounce buffer region */ -- cgit v1.3.1 From 3b4847cbee7cf5c2a6ea19c25003876d0cba4ced Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 7 Nov 2019 08:05:17 +0100 Subject: efi_loader: support building UEFI binaries on sandbox On the sandbox the UEFI binaries must match the host architectures. Adjust the Makefiles. Provide the PE/COFF header and relocation files. Allow building helloworld.efi on the sandbox. Signed-off-by: Heinrich Schuchardt --- Makefile | 19 +++++++++++++++++++ arch/sandbox/config.mk | 28 ++++++++++++++++++++++++++++ arch/sandbox/lib/crt0_sandbox_efi.S | 32 ++++++++++++++++++++++++++++++++ arch/sandbox/lib/reloc_sandbox_efi.c | 32 ++++++++++++++++++++++++++++++++ cmd/Kconfig | 2 +- include/host_arch.h | 24 ++++++++++++++++++++++++ lib/efi_loader/Makefile | 3 +++ 7 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 arch/sandbox/lib/crt0_sandbox_efi.S create mode 100644 arch/sandbox/lib/reloc_sandbox_efi.c create mode 100644 include/host_arch.h (limited to 'lib/efi_loader') diff --git a/Makefile b/Makefile index a9a78c30d67..c746de62bec 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,25 @@ NAME = # o Look for make include files relative to root of kernel src MAKEFLAGS += -rR --include-dir=$(CURDIR) +# Determine host architecture +include include/host_arch.h +MK_ARCH="${shell uname -m}" +unexport HOST_ARCH +ifeq ("x86_64", $(MK_ARCH)) + export HOST_ARCH=$(HOST_ARCH_X86_64) +else ifneq (,$(findstring $(MK_ARCH), "i386" "i486" "i586" "i686")) + export HOST_ARCH=$(HOST_ARCH_X86) +else ifneq (,$(findstring $(MK_ARCH), "aarch64" "armv8l")) + export HOST_ARCH=$(HOST_ARCH_AARCH64) +else ifeq ("armv7l", $(MK_ARCH)) + export HOST_ARCH=$(HOST_ARCH_ARM) +else ifeq ("riscv32", $(MK_ARCH)) + export HOST_ARCH=$(HOST_ARCH_RISCV32) +else ifeq ("riscv64", $(MK_ARCH)) + export HOST_ARCH=$(HOST_ARCH_RISCV64) +endif +undefine MK_ARCH + # Avoid funny character set dependencies unexport LC_ALL LC_COLLATE=C diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 05fbbd7bcc7..a225c9cbfa7 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -27,3 +27,31 @@ cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \ $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot-spl.map -Wl,--gc-sections) CONFIG_ARCH_DEVICE_TREE := sandbox + +ifeq ($(HOST_ARCH),$(HOST_ARCH_X86_64)) +EFI_LDS := ${SRCDIR}/../../../arch/x86/lib/elf_x86_64_efi.lds +EFI_TARGET := --target=efi-app-x86_64 +else ifeq ($(HOST_ARCH),$(HOST_ARCH_X86)) +EFI_LDS := ${SRCDIR}/../../../arch/x86/lib/elf_ia32_efi.lds +EFI_TARGET := --target=efi-app-ia32 +else ifeq ($(HOST_ARCH),$(HOST_ARCH_AARCH64)) +EFI_LDS := ${SRCDIR}/../../../arch/arm/lib/elf_aarch64_efi.lds +OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .data \ + -j .u_boot_list -j .rela.dyn -j .got -j .got.plt \ + -j .binman_sym_table -j .text_rest \ + -j .efi_runtime -j .efi_runtime_rel +else ifeq ($(HOST_ARCH),$(HOST_ARCH_ARM)) +EFI_LDS := ${SRCDIR}/../../../arch/arm/lib/elf_arm_efi.lds +OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \ + -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn \ + -j .binman_sym_table -j .text_rest \ + -j .efi_runtime -j .efi_runtime_rel +else ifeq ($(HOST_ARCH),$(HOST_ARCH_RISCV32)) +EFI_LDS := ${SRCDIR}/../../../arch/riscv/lib/elf_riscv32_efi.lds +else ifeq ($(HOST_ARCH),$(HOST_ARCH_RISCV64)) +EFI_LDS := ${SRCDIR}/../../../arch/riscv/lib/elf_riscv64_efi.lds +endif +EFI_CRT0 := crt0_sandbox_efi.o +EFI_RELOC := reloc_sandbox_efi.o +AFLAGS_crt0_sandbox_efi.o += -DHOST_ARCH="$(HOST_ARCH)" +CFLAGS_reloc_sandbox_efi.o += -DHOST_ARCH="$(HOST_ARCH)" diff --git a/arch/sandbox/lib/crt0_sandbox_efi.S b/arch/sandbox/lib/crt0_sandbox_efi.S new file mode 100644 index 00000000000..b15766c5143 --- /dev/null +++ b/arch/sandbox/lib/crt0_sandbox_efi.S @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * PE/COFF header for EFI applications + * + * Copyright (c) 2019 Heinrich Schuchardt + */ + +#include + +#if HOST_ARCH == HOST_ARCH_X86_64 +#include "../../../arch/x86/lib/crt0_x86_64_efi.S" +#endif + +#if HOST_ARCH == HOST_ARCH_X86 +#include "../../../arch/x86/lib/crt0_ia32_efi.S" +#endif + +#if HOST_ARCH == HOST_ARCH_AARCH64 +#include "../../../arch/arm/lib/crt0_aarch64_efi.S" +#endif + +#if HOST_ARCH == HOST_ARCH_ARM +#include "../../../arch/arm/lib/crt0_arm_efi.S" +#endif + +#if HOST_ARCH == HOST_ARCH_RISCV32 +#include "../../../arch/riscv/lib/crt0_riscv_efi.S" +#endif + +#if HOST_ARCH == HOST_ARCH_RISCV64 +#include "../../../arch/riscv/lib/crt0_riscv_efi.S" +#endif diff --git a/arch/sandbox/lib/reloc_sandbox_efi.c b/arch/sandbox/lib/reloc_sandbox_efi.c new file mode 100644 index 00000000000..a21e6757c55 --- /dev/null +++ b/arch/sandbox/lib/reloc_sandbox_efi.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * position independent shared object relocator + * + * Copyright (c) 2019 Heinrich Schuchardt + */ + +#include + +#if HOST_ARCH == HOST_ARCH_X86_64 +#include "../../../arch/x86/lib/reloc_x86_64_efi.c" +#endif + +#if HOST_ARCH == HOST_ARCH_X86 +#include "../../../arch/x86/lib/reloc_ia32_efi.c" +#endif + +#if HOST_ARCH == HOST_ARCH_AARCH64 +#include "../../../arch/arm/lib/reloc_aarch64_efi.c" +#endif + +#if HOST_ARCH == HOST_ARCH_ARM +#include "../../../arch/arm/lib/reloc_arm_efi.c" +#endif + +#if HOST_ARCH == HOST_ARCH_RISCV32 +#include "../../../arch/riscv/lib/reloc_riscv_efi.c" +#endif + +#if HOST_ARCH == HOST_ARCH_RISCV64 +#include "../../../arch/riscv/lib/reloc_riscv_efi.c" +#endif diff --git a/cmd/Kconfig b/cmd/Kconfig index 99b8a0e2182..cf982ff65e7 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -320,7 +320,7 @@ config CMD_BOOTEFI config CMD_BOOTEFI_HELLO_COMPILE bool "Compile a standard EFI hello world binary for testing" - depends on CMD_BOOTEFI && !CPU_V7M && !SANDBOX + depends on CMD_BOOTEFI && !CPU_V7M default y help This compiles a standard EFI hello world application with U-Boot so diff --git a/include/host_arch.h b/include/host_arch.h new file mode 100644 index 00000000000..169d4945136 --- /dev/null +++ b/include/host_arch.h @@ -0,0 +1,24 @@ +#if 0 +# SPDX SPDX-License-Identifier: GPL-2.0+ +# +# Constants defining the host architecture in assembler, C, and make files. +# The values are arbitrary. +# +# Copyright 2019 Heinrich Schuchardt +#endif + +#if 0 +export HOST_ARCH_AARCH64=0xaa64 +export HOST_ARCH_ARM=0x00a7 +export HOST_ARCH_RISCV32=0x5032 +export HOST_ARCH_RISCV64=0x5064 +export HOST_ARCH_X86=0x0386 +export HOST_ARCH_X86_64=0x8664 +#endif + +#define HOST_ARCH_AARCH64 0xaa64 +#define HOST_ARCH_ARM 0x00a7 +#define HOST_ARCH_RISCV32 0x5032 +#define HOST_ARCH_RISCV64 0x5064 +#define HOST_ARCH_X86 0x0386 +#define HOST_ARCH_X86_64 0x8664 diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 01769ea58ba..7db40602861 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -6,6 +6,9 @@ # This file only gets included with CONFIG_EFI_LOADER set, so all # object inclusion implicitly depends on it +asflags-y += -DHOST_ARCH="$(HOST_ARCH)" +ccflags-y += -DHOST_ARCH="$(HOST_ARCH)" + CFLAGS_efi_boottime.o += \ -DFW_VERSION="0x$(VERSION)" \ -DFW_PATCHLEVEL="0x$(PATCHLEVEL)" -- cgit v1.3.1