Commit c7ae3dfdccc171543804d6577ee41ab03e7a09bc

Authored by Simon Glass
Committed by Alexander Graf
1 parent bb1ae55948

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>

Showing 7 changed files with 107 additions and 6 deletions Side-by-side Diff

... ... @@ -181,6 +181,15 @@
181 181 help
182 182 Boot an EFI image from memory.
183 183  
  184 +config CMD_BOOTEFI_HELLO
  185 + bool "Allow booting a standard EFI hello world for testing"
  186 + depends on CMD_BOOTEFI && NEED_CRT0_ENABLEMENT
  187 + help
  188 + This adds a standard EFI hello world application to U-Boot so that
  189 + it can be used with the 'bootefi hello' command. This is useful
  190 + for testing that EFI is working at a basic level, and for bringing
  191 + up EFI support on a new architecture.
  192 +
184 193 config CMD_ELF
185 194 bool "bootelf, bootvx"
186 195 default y
... ... @@ -239,13 +239,23 @@
239 239  
240 240 if (argc < 2)
241 241 return CMD_RET_USAGE;
242   - saddr = argv[1];
  242 +#ifdef CONFIG_CMD_BOOTEFI_HELLO
  243 + if (!strcmp(argv[1], "hello")) {
  244 + ulong size = __efi_hello_world_end - __efi_hello_world_begin;
243 245  
244   - addr = simple_strtoul(saddr, NULL, 16);
  246 + addr = CONFIG_SYS_LOAD_ADDR;
  247 + memcpy((char *)addr, __efi_hello_world_begin, size);
  248 + } else
  249 +#endif
  250 + {
  251 + saddr = argv[1];
245 252  
246   - if (argc > 2) {
247   - sfdt = argv[2];
248   - fdt_addr = simple_strtoul(sfdt, NULL, 16);
  253 + addr = simple_strtoul(saddr, NULL, 16);
  254 +
  255 + if (argc > 2) {
  256 + sfdt = argv[2];
  257 + fdt_addr = simple_strtoul(sfdt, NULL, 16);
  258 + }
249 259 }
250 260  
251 261 printf("## Starting EFI application at %08lx ...\n", addr);
... ... @@ -263,7 +273,12 @@
263 273 "<image address> [fdt address]\n"
264 274 " - boot EFI payload stored at address <image address>.\n"
265 275 " If specified, the device tree located at <fdt address> gets\n"
266   - " exposed as EFI configuration table.\n";
  276 + " exposed as EFI configuration table.\n"
  277 +#ifdef CONFIG_CMD_BOOTEFI_HELLO
  278 + "hello\n"
  279 + " - boot a sample Hello World application stored within U-Boot"
  280 +#endif
  281 + ;
267 282 #endif
268 283  
269 284 U_BOOT_CMD(
... ... @@ -310,6 +310,20 @@
310 310 Simple use cases like "Plug this SD card into my ARM device and it just
311 311 boots into grub which boots into Linux", work very well.
312 312  
  313 +
  314 +Running HelloWord.efi
  315 +---------------------
  316 +
  317 +You can run a simple 'hello world' EFI program in U-Boot.
  318 +Enable the option CONFIG_CMD_BOOTEFI_HELLO.
  319 +
  320 +Then you can boot into U-Boot and type:
  321 +
  322 + > bootefi hello
  323 +
  324 +The 'hello world EFI' program will then run, print a message and exit.
  325 +
  326 +
313 327 Future work
314 328 -----------
315 329  
include/asm-generic/sections.h
... ... @@ -22,6 +22,8 @@
22 22 extern char __entry_text_start[], __entry_text_end[];
23 23 extern char __initdata_begin[], __initdata_end[];
24 24 extern char __start_rodata[], __end_rodata[];
  25 +extern char __efi_hello_world_begin[];
  26 +extern char __efi_hello_world_end[];
25 27  
26 28 /* Start and end of .ctors section - used for constructor calls. */
27 29 extern char __ctors_start[], __ctors_end[];
lib/efi_loader/Makefile
... ... @@ -7,6 +7,10 @@
7 7 # This file only gets included with CONFIG_EFI_LOADER set, so all
8 8 # object inclusion implicitly depends on it
9 9  
  10 +CFLAGS_helloworld.o := $(CFLAGS_EFI)
  11 +CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI)
  12 +
  13 +obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
10 14 obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o
11 15 obj-y += efi_memory.o
12 16 obj-$(CONFIG_LCD) += efi_gop.o
lib/efi_loader/helloworld.c
  1 +/*
  2 + * EFI hello world
  3 + *
  4 + * Copyright (c) 2016 Google, Inc
  5 + * Written by Simon Glass <sjg@chromium.org>
  6 + *
  7 + * SPDX-License-Identifier: GPL-2.0+
  8 + */
  9 +
  10 +#include <common.h>
  11 +#include <part_efi.h>
  12 +#include <efi_api.h>
  13 +
  14 +efi_status_t EFIAPI efi_main(efi_handle_t handle,
  15 + struct efi_system_table *systable)
  16 +{
  17 + struct efi_simple_text_output_protocol *con_out = systable->con_out;
  18 + struct efi_boot_services *boottime = systable->boottime;
  19 +
  20 + con_out->output_string(con_out, L"Hello, world!\n");
  21 + boottime->exit(handle, 0, 0, NULL);
  22 +
  23 + return EFI_SUCCESS;
  24 +}
scripts/Makefile.lib
... ... @@ -321,6 +321,39 @@
321 321 $(obj)/%.S: $(src)/%.ttf
322 322 $(call cmd,S_ttf)
323 323  
  324 +# EFI Hello World application
  325 +# ---------------------------------------------------------------------------
  326 +
  327 +# Generate an assembly file to wrap the EFI app
  328 +cmd_S_efi= \
  329 +( \
  330 + echo '.section .rodata.efi.init,"a"'; \
  331 + echo '.balign 16'; \
  332 + echo '.global __efi_hello_world_begin'; \
  333 + echo '__efi_hello_world_begin:'; \
  334 + echo '.incbin "$<" '; \
  335 + echo '__efi_hello_world_end:'; \
  336 + echo '.global __efi_hello_world_end'; \
  337 + echo '.balign 16'; \
  338 +) > $@
  339 +
  340 +$(obj)/%_efi.S: $(obj)/%.efi
  341 + $(call cmd,S_efi)
  342 +
  343 +$(obj)/%.efi: $(obj)/%.so
  344 + $(OBJCOPY) -j .header -j .text -j .sdata -j .data -j .dynamic \
  345 + -j .dynsym -j .rel* -j .rela* -j .reloc \
  346 + $(if $(EFI_TARGET),$(EFI_TARGET),-O binary) $^ $@
  347 +
  348 +EFI_LDS_PATH = $(srctree)/arch/$(ARCH)/lib/$(EFI_LDS)
  349 +
  350 +$(obj)/helloworld.so: $(EFI_LDS_PATH)
  351 +
  352 +$(obj)/helloworld.so: $(obj)/helloworld.o arch/$(ARCH)/lib/$(EFI_CRT0) \
  353 + arch/$(ARCH)/lib/$(EFI_RELOC)
  354 + $(LD) -nostdlib -znocombreloc -T $(EFI_LDS_PATH) -shared -Bsymbolic \
  355 + $^ -o $@
  356 +
324 357 # ACPI
325 358 # ---------------------------------------------------------------------------
326 359 quiet_cmd_acpi_c_asl= ASL $<