Re: [U-Boot] [PATCH 34/48] efi: Add support for loading U-Boot through an EFI stub
Hi Simon, On Wed, Jul 22, 2015 at 11:49 PM, Simon Glass s...@chromium.org wrote: It is useful to be able to load U-Boot onto a board even it is it already running EFI. This can allow access to the U-Boot command interface, flexible booting options and easier development. The easiest way to do this is to build U-Boot as a binary blob and have an EFI stub copy it into RAM. Add support for this feature, targeting 32-bit initially. Also add a way to detect when U-Boot has been loaded via a stub. This goes in common.h since it needs to be widely available so that we avoid redoing initialisation that should be skipped. Signed-off-by: Simon Glass s...@chromium.org --- Makefile | 32 ++ include/common.h | 7 ++ include/efi.h | 4 + lib/efi/Kconfig| 21 lib/efi/Makefile | 9 ++ lib/efi/efi_stub.c | 293 + 6 files changed, 366 insertions(+) create mode 100644 lib/efi/efi_stub.c diff --git a/Makefile b/Makefile index 91ebc2e..9f863e1 100644 --- a/Makefile +++ b/Makefile @@ -753,6 +753,7 @@ ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:%=%) endif ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf ALL-$(CONFIG_ARCH_EFI) += u-boot.efi +ALL-$(CONFIG_EFI_STUB) += u-boot-payload.efi ifneq ($(BUILD_ROM),) ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom @@ -1085,6 +1086,37 @@ OBJCOPYFLAGS_u-boot.efi := $(OBJCOPYFLAGS_EFI) u-boot.efi: u-boot FORCE $(call if_changed,zobjcopy) +# Generate an assembly file to wrap a binary file +quiet_cmd_bin_S = BIN $@ +cmd_bin_S =\ +( \ + echo '.section .u_boot_bin.init.rodata,a';\ + echo '.balign 16'; \ + echo '.global __u_boot_bin_begin'; \ + echo '__u_boot_bin_begin:'; \ + echo '.incbin $ '; \ + echo '__u_boot_bin_end:'; \ + echo '.global __u_boot_bin_end';\ + echo '.balign 16'; \ +) $@ + Please check another approach @ http://patchwork.ozlabs.org/patch/499458/ +u-boot-dtb.bin.S: u-boot-dtb.bin FORCE + $(call if_changed,bin_S) + +u-boot-payload.lds: $(LDSCRIPT_EFI) FORCE + $(call if_changed_dep,cpp_lds) + +u-boot-payload: u-boot-dtb.bin.o u-boot-payload.lds \ + FORCE + $(LD) $(LDFLAGS_EFI) -o $@ \ + -T u-boot-payload.lds \ + lib/efi/efi.o lib/efi/efi_stub.o u-boot-dtb.bin.o \ + $(addprefix arch/$(ARCH)/lib/,$(EFISTUB)) Please change to use cmd_xxx to avoid putting compiler message to the console. + +OBJCOPYFLAGS_u-boot-payload.efi := $(OBJCOPYFLAGS_EFI) +u-boot-payload.efi: u-boot-payload FORCE + $(call if_changed,zobjcopy) + u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE $(call if_changed,cat) diff --git a/include/common.h b/include/common.h index 8f4b2ec..406fb33 100644 --- a/include/common.h +++ b/include/common.h @@ -1010,6 +1010,13 @@ int cpu_release(int nr, int argc, char * const argv[]); #define DEFINE_CACHE_ALIGN_BUFFER(type, name, size)\ DEFINE_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN) +/* Avoid using CONFIG_EFI_STUB directly as we may boot from other loaders */ +#ifdef CONFIG_EFI_STUB +#define ll_boot_init() false +#else +#define ll_boot_init() true +#endif + /* Pull in stuff for the build system */ #ifdef DO_DEPS_ONLY # include environment.h diff --git a/include/efi.h b/include/efi.h index 66ef6c3..edc8cd9 100644 --- a/include/efi.h +++ b/include/efi.h @@ -268,11 +268,15 @@ struct efi_priv { /* Base address of the EFI image */ extern char ImageBase[]; +/* Start and end of U-Boot image (for payload) */ +extern char __u_boot_bin_begin[], __u_boot_bin_end[]; + /** * efi_get_sys_table() - Get access to the main EFI system table * * @return pointer to EFI system table */ + struct efi_system_table *efi_get_sys_table(void); /** diff --git a/lib/efi/Kconfig b/lib/efi/Kconfig index 2b3dbd4..f1a8873 100644 --- a/lib/efi/Kconfig +++ b/lib/efi/Kconfig @@ -20,6 +20,11 @@ config ARCH_EFI command problem and memory and I/O functions. Use 'reset' to return to EFI. +config EFI_STUB + bool Support running as an EFI payload + +endchoice + config EFI_RAM_SIZE hex Amount of EFI RAM for U-Boot depends on ARCH_EFI @@ -30,4 +35,20 @@ config EFI_RAM_SIZE other smaller amounts) and it can never be increased after that. It is used as the RAM size in withU-Boot. +choice + prompt EFI 32/64-bit selection + depends on EFI_STUB + help + EFI does not support mixing 32-bit and 64-bit modes. This is a + significant problem because it means that you must build a stub with +
[U-Boot] [PATCH 34/48] efi: Add support for loading U-Boot through an EFI stub
It is useful to be able to load U-Boot onto a board even it is it already running EFI. This can allow access to the U-Boot command interface, flexible booting options and easier development. The easiest way to do this is to build U-Boot as a binary blob and have an EFI stub copy it into RAM. Add support for this feature, targeting 32-bit initially. Also add a way to detect when U-Boot has been loaded via a stub. This goes in common.h since it needs to be widely available so that we avoid redoing initialisation that should be skipped. Signed-off-by: Simon Glass s...@chromium.org --- Makefile | 32 ++ include/common.h | 7 ++ include/efi.h | 4 + lib/efi/Kconfig| 21 lib/efi/Makefile | 9 ++ lib/efi/efi_stub.c | 293 + 6 files changed, 366 insertions(+) create mode 100644 lib/efi/efi_stub.c diff --git a/Makefile b/Makefile index 91ebc2e..9f863e1 100644 --- a/Makefile +++ b/Makefile @@ -753,6 +753,7 @@ ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:%=%) endif ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf ALL-$(CONFIG_ARCH_EFI) += u-boot.efi +ALL-$(CONFIG_EFI_STUB) += u-boot-payload.efi ifneq ($(BUILD_ROM),) ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom @@ -1085,6 +1086,37 @@ OBJCOPYFLAGS_u-boot.efi := $(OBJCOPYFLAGS_EFI) u-boot.efi: u-boot FORCE $(call if_changed,zobjcopy) +# Generate an assembly file to wrap a binary file +quiet_cmd_bin_S = BIN $@ +cmd_bin_S =\ +( \ + echo '.section .u_boot_bin.init.rodata,a';\ + echo '.balign 16'; \ + echo '.global __u_boot_bin_begin'; \ + echo '__u_boot_bin_begin:'; \ + echo '.incbin $ '; \ + echo '__u_boot_bin_end:'; \ + echo '.global __u_boot_bin_end';\ + echo '.balign 16'; \ +) $@ + +u-boot-dtb.bin.S: u-boot-dtb.bin FORCE + $(call if_changed,bin_S) + +u-boot-payload.lds: $(LDSCRIPT_EFI) FORCE + $(call if_changed_dep,cpp_lds) + +u-boot-payload: u-boot-dtb.bin.o u-boot-payload.lds \ + FORCE + $(LD) $(LDFLAGS_EFI) -o $@ \ + -T u-boot-payload.lds \ + lib/efi/efi.o lib/efi/efi_stub.o u-boot-dtb.bin.o \ + $(addprefix arch/$(ARCH)/lib/,$(EFISTUB)) + +OBJCOPYFLAGS_u-boot-payload.efi := $(OBJCOPYFLAGS_EFI) +u-boot-payload.efi: u-boot-payload FORCE + $(call if_changed,zobjcopy) + u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE $(call if_changed,cat) diff --git a/include/common.h b/include/common.h index 8f4b2ec..406fb33 100644 --- a/include/common.h +++ b/include/common.h @@ -1010,6 +1010,13 @@ int cpu_release(int nr, int argc, char * const argv[]); #define DEFINE_CACHE_ALIGN_BUFFER(type, name, size)\ DEFINE_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN) +/* Avoid using CONFIG_EFI_STUB directly as we may boot from other loaders */ +#ifdef CONFIG_EFI_STUB +#define ll_boot_init() false +#else +#define ll_boot_init() true +#endif + /* Pull in stuff for the build system */ #ifdef DO_DEPS_ONLY # include environment.h diff --git a/include/efi.h b/include/efi.h index 66ef6c3..edc8cd9 100644 --- a/include/efi.h +++ b/include/efi.h @@ -268,11 +268,15 @@ struct efi_priv { /* Base address of the EFI image */ extern char ImageBase[]; +/* Start and end of U-Boot image (for payload) */ +extern char __u_boot_bin_begin[], __u_boot_bin_end[]; + /** * efi_get_sys_table() - Get access to the main EFI system table * * @return pointer to EFI system table */ + struct efi_system_table *efi_get_sys_table(void); /** diff --git a/lib/efi/Kconfig b/lib/efi/Kconfig index 2b3dbd4..f1a8873 100644 --- a/lib/efi/Kconfig +++ b/lib/efi/Kconfig @@ -20,6 +20,11 @@ config ARCH_EFI command problem and memory and I/O functions. Use 'reset' to return to EFI. +config EFI_STUB + bool Support running as an EFI payload + +endchoice + config EFI_RAM_SIZE hex Amount of EFI RAM for U-Boot depends on ARCH_EFI @@ -30,4 +35,20 @@ config EFI_RAM_SIZE other smaller amounts) and it can never be increased after that. It is used as the RAM size in withU-Boot. +choice + prompt EFI 32/64-bit selection + depends on EFI_STUB + help + EFI does not support mixing 32-bit and 64-bit modes. This is a + significant problem because it means that you must build a stub with + the correct type for EFI to load it correctly. If you are using + 32-bit EFI, select 32-bit here, else select 64-bit. Failure to do + this may produce no error message - it just won't start! + +config EFI_STUB_32BIT + bool Produce a stub for running with 32-bit EFI + +config EFI_STUB_64BIT + bool Produce a stub for running with