efi: Add support for a hello world test program
It is useful to have a basic sanity check for EFI loader support. Add a 'bootefi hello' command which loads HelloWord.efi and runs it under U-Boot. Signed-off-by: Simon Glass <sjg@chromium.org> [agraf: Fix documentation, add unfulfilled kconfig dep] Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
bb1ae55948
commit
c7ae3dfdcc
|
@ -181,6 +181,15 @@ config CMD_BOOTEFI
|
||||||
help
|
help
|
||||||
Boot an EFI image from memory.
|
Boot an EFI image from memory.
|
||||||
|
|
||||||
|
config CMD_BOOTEFI_HELLO
|
||||||
|
bool "Allow booting a standard EFI hello world for testing"
|
||||||
|
depends on CMD_BOOTEFI && NEED_CRT0_ENABLEMENT
|
||||||
|
help
|
||||||
|
This adds a standard EFI hello world application to U-Boot so that
|
||||||
|
it can be used with the 'bootefi hello' command. This is useful
|
||||||
|
for testing that EFI is working at a basic level, and for bringing
|
||||||
|
up EFI support on a new architecture.
|
||||||
|
|
||||||
config CMD_ELF
|
config CMD_ELF
|
||||||
bool "bootelf, bootvx"
|
bool "bootelf, bootvx"
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -239,13 +239,23 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
return CMD_RET_USAGE;
|
return CMD_RET_USAGE;
|
||||||
saddr = argv[1];
|
#ifdef CONFIG_CMD_BOOTEFI_HELLO
|
||||||
|
if (!strcmp(argv[1], "hello")) {
|
||||||
|
ulong size = __efi_hello_world_end - __efi_hello_world_begin;
|
||||||
|
|
||||||
addr = simple_strtoul(saddr, NULL, 16);
|
addr = CONFIG_SYS_LOAD_ADDR;
|
||||||
|
memcpy((char *)addr, __efi_hello_world_begin, size);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
saddr = argv[1];
|
||||||
|
|
||||||
if (argc > 2) {
|
addr = simple_strtoul(saddr, NULL, 16);
|
||||||
sfdt = argv[2];
|
|
||||||
fdt_addr = simple_strtoul(sfdt, NULL, 16);
|
if (argc > 2) {
|
||||||
|
sfdt = argv[2];
|
||||||
|
fdt_addr = simple_strtoul(sfdt, NULL, 16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("## Starting EFI application at %08lx ...\n", addr);
|
printf("## Starting EFI application at %08lx ...\n", addr);
|
||||||
|
@ -263,7 +273,12 @@ static char bootefi_help_text[] =
|
||||||
"<image address> [fdt address]\n"
|
"<image address> [fdt address]\n"
|
||||||
" - boot EFI payload stored at address <image address>.\n"
|
" - boot EFI payload stored at address <image address>.\n"
|
||||||
" If specified, the device tree located at <fdt address> gets\n"
|
" If specified, the device tree located at <fdt address> gets\n"
|
||||||
" exposed as EFI configuration table.\n";
|
" exposed as EFI configuration table.\n"
|
||||||
|
#ifdef CONFIG_CMD_BOOTEFI_HELLO
|
||||||
|
"hello\n"
|
||||||
|
" - boot a sample Hello World application stored within U-Boot"
|
||||||
|
#endif
|
||||||
|
;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
U_BOOT_CMD(
|
U_BOOT_CMD(
|
||||||
|
|
|
@ -310,6 +310,20 @@ Removable media booting (search for /efi/boot/boota{a64,arm}.efi) is supported.
|
||||||
Simple use cases like "Plug this SD card into my ARM device and it just
|
Simple use cases like "Plug this SD card into my ARM device and it just
|
||||||
boots into grub which boots into Linux", work very well.
|
boots into grub which boots into Linux", work very well.
|
||||||
|
|
||||||
|
|
||||||
|
Running HelloWord.efi
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
You can run a simple 'hello world' EFI program in U-Boot.
|
||||||
|
Enable the option CONFIG_CMD_BOOTEFI_HELLO.
|
||||||
|
|
||||||
|
Then you can boot into U-Boot and type:
|
||||||
|
|
||||||
|
> bootefi hello
|
||||||
|
|
||||||
|
The 'hello world EFI' program will then run, print a message and exit.
|
||||||
|
|
||||||
|
|
||||||
Future work
|
Future work
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ extern char __kprobes_text_start[], __kprobes_text_end[];
|
||||||
extern char __entry_text_start[], __entry_text_end[];
|
extern char __entry_text_start[], __entry_text_end[];
|
||||||
extern char __initdata_begin[], __initdata_end[];
|
extern char __initdata_begin[], __initdata_end[];
|
||||||
extern char __start_rodata[], __end_rodata[];
|
extern char __start_rodata[], __end_rodata[];
|
||||||
|
extern char __efi_hello_world_begin[];
|
||||||
|
extern char __efi_hello_world_end[];
|
||||||
|
|
||||||
/* Start and end of .ctors section - used for constructor calls. */
|
/* Start and end of .ctors section - used for constructor calls. */
|
||||||
extern char __ctors_start[], __ctors_end[];
|
extern char __ctors_start[], __ctors_end[];
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
# This file only gets included with CONFIG_EFI_LOADER set, so all
|
# This file only gets included with CONFIG_EFI_LOADER set, so all
|
||||||
# object inclusion implicitly depends on it
|
# object inclusion implicitly depends on it
|
||||||
|
|
||||||
|
CFLAGS_helloworld.o := $(CFLAGS_EFI)
|
||||||
|
CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI)
|
||||||
|
|
||||||
|
obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
|
||||||
obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o
|
obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o
|
||||||
obj-y += efi_memory.o
|
obj-y += efi_memory.o
|
||||||
obj-$(CONFIG_LCD) += efi_gop.o
|
obj-$(CONFIG_LCD) += efi_gop.o
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* EFI hello world
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Google, Inc
|
||||||
|
* Written by Simon Glass <sjg@chromium.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <part_efi.h>
|
||||||
|
#include <efi_api.h>
|
||||||
|
|
||||||
|
efi_status_t EFIAPI efi_main(efi_handle_t handle,
|
||||||
|
struct efi_system_table *systable)
|
||||||
|
{
|
||||||
|
struct efi_simple_text_output_protocol *con_out = systable->con_out;
|
||||||
|
struct efi_boot_services *boottime = systable->boottime;
|
||||||
|
|
||||||
|
con_out->output_string(con_out, L"Hello, world!\n");
|
||||||
|
boottime->exit(handle, 0, 0, NULL);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
|
@ -321,6 +321,39 @@ cmd_S_ttf= \
|
||||||
$(obj)/%.S: $(src)/%.ttf
|
$(obj)/%.S: $(src)/%.ttf
|
||||||
$(call cmd,S_ttf)
|
$(call cmd,S_ttf)
|
||||||
|
|
||||||
|
# EFI Hello World application
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Generate an assembly file to wrap the EFI app
|
||||||
|
cmd_S_efi= \
|
||||||
|
( \
|
||||||
|
echo '.section .rodata.efi.init,"a"'; \
|
||||||
|
echo '.balign 16'; \
|
||||||
|
echo '.global __efi_hello_world_begin'; \
|
||||||
|
echo '__efi_hello_world_begin:'; \
|
||||||
|
echo '.incbin "$<" '; \
|
||||||
|
echo '__efi_hello_world_end:'; \
|
||||||
|
echo '.global __efi_hello_world_end'; \
|
||||||
|
echo '.balign 16'; \
|
||||||
|
) > $@
|
||||||
|
|
||||||
|
$(obj)/%_efi.S: $(obj)/%.efi
|
||||||
|
$(call cmd,S_efi)
|
||||||
|
|
||||||
|
$(obj)/%.efi: $(obj)/%.so
|
||||||
|
$(OBJCOPY) -j .header -j .text -j .sdata -j .data -j .dynamic \
|
||||||
|
-j .dynsym -j .rel* -j .rela* -j .reloc \
|
||||||
|
$(if $(EFI_TARGET),$(EFI_TARGET),-O binary) $^ $@
|
||||||
|
|
||||||
|
EFI_LDS_PATH = $(srctree)/arch/$(ARCH)/lib/$(EFI_LDS)
|
||||||
|
|
||||||
|
$(obj)/helloworld.so: $(EFI_LDS_PATH)
|
||||||
|
|
||||||
|
$(obj)/helloworld.so: $(obj)/helloworld.o arch/$(ARCH)/lib/$(EFI_CRT0) \
|
||||||
|
arch/$(ARCH)/lib/$(EFI_RELOC)
|
||||||
|
$(LD) -nostdlib -znocombreloc -T $(EFI_LDS_PATH) -shared -Bsymbolic \
|
||||||
|
$^ -o $@
|
||||||
|
|
||||||
# ACPI
|
# ACPI
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
quiet_cmd_acpi_c_asl= ASL $<
|
quiet_cmd_acpi_c_asl= ASL $<
|
||||||
|
|
Loading…
Reference in New Issue