From cab6f06c14a2a059621ef51b241a0089beb48cfd Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 30 Oct 2019 20:13:24 +0100 Subject: [PATCH 1/5] 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(-) diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index ac5e6f7e14..17a0c5bb45 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; From 89cb6a5dd6d44dc7293845d63ee29fe6b7cd1d09 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Mon, 7 Oct 2019 14:59:39 +0900 Subject: [PATCH 2/5] 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(-) diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 861fcaf374..ed7fb3f7d3 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, From 7264e21fdead677687934eecda6ac98f37851acf Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 8 Nov 2019 20:42:53 +0100 Subject: [PATCH 3/5] 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(-) diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 83cbc9154f..d46001f608 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 */ From 3b4847cbee7cf5c2a6ea19c25003876d0cba4ced Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 7 Nov 2019 08:05:17 +0100 Subject: [PATCH 4/5] 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 diff --git a/Makefile b/Makefile index a9a78c30d6..c746de62be 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 05fbbd7bcc..a225c9cbfa 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 0000000000..b15766c514 --- /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 0000000000..a21e6757c5 --- /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 99b8a0e218..cf982ff65e 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 0000000000..169d494513 --- /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 01769ea58b..7db4060286 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)" From 2e716b8e299309139daa9513707951c622fc2bdf Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 8 Nov 2019 21:17:58 +0100 Subject: [PATCH 5/5] efi_selftest: enable all UEFI unit tests on the sandbox As we can build relocation code for the sandbox now we should enable the unit tests that had to be disabled up to now. Signed-off-by: Heinrich Schuchardt --- lib/efi_selftest/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 8348014077..487cb4c674 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -5,6 +5,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_selftest_miniapp_exit.o := $(CFLAGS_EFI) -Os -ffreestanding CFLAGS_REMOVE_efi_selftest_miniapp_exit.o := $(CFLAGS_NON_EFI) CFLAGS_efi_selftest_miniapp_return.o := $(CFLAGS_EFI) -Os -ffreestanding @@ -55,8 +58,8 @@ obj-y += efi_selftest_block_device.o endif # TODO: As of v2019.10 the relocation code for the EFI application cannot -# be built on ARMv7-M and Sandbox. -ifeq ($(CONFIG_SANDBOX)$(CONFIG_CPU_V7M),) +# be built on ARMv7-M. +ifeq ($(CONFIG_CPU_V7M),) obj-y += \ efi_selftest_exception.o \