Commit c7ae3dfdccc171543804d6577ee41ab03e7a09bc
Committed by
Alexander Graf
1 parent
bb1ae55948
Exists in
v2017.01-smarct4x
and in
25 other branches
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
cmd/Kconfig
... | ... | @@ -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 |
cmd/bootefi.c
... | ... | @@ -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( |
doc/README.efi
... | ... | @@ -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 $< |