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:
Simon Glass 2016-11-07 08:47:08 -07:00 committed by Alexander Graf
parent bb1ae55948
commit c7ae3dfdcc
7 changed files with 107 additions and 6 deletions

View file

@ -181,6 +181,15 @@ config CMD_BOOTEFI
help
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
bool "bootelf, bootvx"
default y

View file

@ -239,13 +239,23 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (argc < 2)
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) {
sfdt = argv[2];
fdt_addr = simple_strtoul(sfdt, NULL, 16);
addr = simple_strtoul(saddr, NULL, 16);
if (argc > 2) {
sfdt = argv[2];
fdt_addr = simple_strtoul(sfdt, NULL, 16);
}
}
printf("## Starting EFI application at %08lx ...\n", addr);
@ -263,7 +273,12 @@ static char bootefi_help_text[] =
"<image address> [fdt address]\n"
" - boot EFI payload stored at address <image address>.\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
U_BOOT_CMD(

View file

@ -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
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
-----------

View file

@ -22,6 +22,8 @@ extern char __kprobes_text_start[], __kprobes_text_end[];
extern char __entry_text_start[], __entry_text_end[];
extern char __initdata_begin[], __initdata_end[];
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. */
extern char __ctors_start[], __ctors_end[];

View file

@ -7,6 +7,10 @@
# This file only gets included with CONFIG_EFI_LOADER set, so all
# 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_memory.o
obj-$(CONFIG_LCD) += efi_gop.o

View file

@ -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;
}

View file

@ -321,6 +321,39 @@ cmd_S_ttf= \
$(obj)/%.S: $(src)/%.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
# ---------------------------------------------------------------------------
quiet_cmd_acpi_c_asl= ASL $<