[U-Boot] [PATCH 00/16] efi: Enable basic sandbox support for EFI loader

Rob Clark robdclark at gmail.com
Mon Sep 18 14:30:39 UTC 2017


On Mon, Sep 18, 2017 at 9:31 AM, Rob Clark <robdclark at gmail.com> wrote:
> On Mon, Sep 18, 2017 at 9:18 AM, Rob Clark <robdclark at gmail.com> wrote:
>> On Sun, Sep 17, 2017 at 11:48 PM, Heinrich Schuchardt
>> <xypron.glpk at gmx.de> wrote:
>>> On 09/18/2017 12:59 AM, Simon Glass wrote:
>>>> A limitation of the EFI loader at present is that it does not build with
>>>> sandbox. This makes it hard to write tests, since sandbox is used for most
>>>> testing in U-Boot.
>>>>
>>>> This series enables the EFI loader feature. It allows sandbox to build and
>>>> run a trivial function which calls the EFI API to output a message.
>>>>
>>>> Much work remains but this should serve as a basis for adding tests more
>>>> easily for EFI loader.
>>>>
>>>> This series sits on top of Heinrich's recent EFI test series. It is
>>>> available at u-boot-dm/efi-working
>>>>
>>>>
>>>> Simon Glass (16):
>>>>   efi: Update efi_smbios_register() to return error code
>>>>   efi: Move the init check inside efi_init_obj_list()
>>>>   efi: Add error checking for efi_init_obj_list()
>>>>   efi: Add a TODO to efi_init_obj_list()
>>>>   efi: Correct header order in efi_memory
>>>>   efi: sandbox: Adjust memory setup for sandbox
>>>>   sandbox: smbios: Update to support sandbox
>>>>   sandbox: Add a setjmp() implementation
>>>>   efi: sandbox: Add required linker sections
>>>>   efi: sandbox: Add distroboot support
>>>>   Define board_quiesce_devices() in a shared location
>>>>   Add a comment for board_quiesce_devices()
>>>>   efi: sandbox: Add relocation constants
>>>>   efi: Add a comment about duplicated ELF constants
>>>>   efi: sandbox: Enable EFI loader builder for sandbox
>>>>   efi: sandbox: Add a simple 'bootefi test' command
>>>>
>>>>  arch/arm/include/asm/u-boot-arm.h |  1 -
>>>>  arch/sandbox/cpu/cpu.c            | 13 ++++++++++
>>>>  arch/sandbox/cpu/os.c             | 17 ++++++++++++
>>>>  arch/sandbox/cpu/u-boot.lds       | 29 +++++++++++++++++++++
>>>>  arch/sandbox/include/asm/setjmp.h | 21 +++++++++++++++
>>>>  arch/sandbox/lib/Makefile         |  2 +-
>>>>  arch/sandbox/lib/sections.c       | 12 +++++++++
>>>>  arch/x86/include/asm/u-boot-x86.h |  1 -
>>>>  arch/x86/lib/bootm.c              |  4 ---
>>>>  cmd/bootefi.c                     | 54 ++++++++++++++++++++++++++++++++++-----
>>>>  common/bootm.c                    |  4 +++
>>>>  configs/sandbox_defconfig         |  1 +
>>>>  include/bootm.h                   |  8 ++++++
>>>>  include/config_distro_bootcmd.h   |  2 +-
>>>>  include/efi_loader.h              | 13 ++++++++--
>>>>  include/os.h                      | 21 +++++++++++++++
>>>>  lib/efi_loader/Kconfig            | 12 ++++++++-
>>>>  lib/efi_loader/Makefile           |  1 +
>>>>  lib/efi_loader/efi_boottime.c     |  4 +++
>>>>  lib/efi_loader/efi_memory.c       | 33 +++++++++++++-----------
>>>>  lib/efi_loader/efi_runtime.c      |  7 +++++
>>>>  lib/efi_loader/efi_smbios.c       |  6 +++--
>>>>  lib/efi_loader/efi_test.c         | 17 ++++++++++++
>>>>  lib/smbios.c                      | 38 ++++++++++++++++++++-------
>>>>  24 files changed, 277 insertions(+), 44 deletions(-)
>>>>  create mode 100644 arch/sandbox/include/asm/setjmp.h
>>>>  create mode 100644 arch/sandbox/lib/sections.c
>>>>  create mode 100644 lib/efi_loader/efi_test.c
>>>>
>>> Thanks for enabling efi_loader on sandbox. That will make many things
>>> easier.
>>>
>>> Unfortunately
>>> efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
>>>                                  struct efi_system_table *systab)
>>> {
>>> ...
>>>         boottime = systable->boottime;
>>> ...
>>>         ret = boottime->allocate_pool(EFI_BOOT_SERVICES_DATA, map_size,
>>>                                       (void **)&memory_map);
>>> leads to a segmentation fault:
>>
>> I'm seeing something similar, because:
>>
>> (gdb) print gd->bd->bi_dram[0]
>> $2 = {start = 0, size = 134217728}
>>
>> u-boot expects 1:1 phys:virt mapping, so that probably won't work.
>
> The following quick hack works.. something similar could probably be
> smashed in to ""
>
> --------
> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
> index cddafe2d43..da2079a4b1 100644
> --- a/lib/efi_loader/efi_memory.c
> +++ b/lib/efi_loader/efi_memory.c
> @@ -459,9 +459,10 @@ int efi_memory_init(void)
>      unsigned long uboot_start, uboot_pages;
>      unsigned long uboot_stack_size = 16 * 1024 * 1024;
>
> -    efi_add_known_memory();
>
>      if (!IS_ENABLED(CONFIG_SANDBOX)) {
> +        efi_add_known_memory();
> +
>          /* Add U-Boot */
>          uboot_start = (gd->start_addr_sp - uboot_stack_size) &
>                  ~EFI_PAGE_MASK;
> @@ -476,6 +477,12 @@ int efi_memory_init(void)
>          runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
>          efi_add_memory_map(runtime_start, runtime_pages,
>                     EFI_RUNTIME_SERVICES_CODE, false);
> +    } else {
> +#define SZ_256M    0x10000000
> +        size_t sz = SZ_256M;
> +        void *ram = os_malloc(sz);
> +        efi_add_memory_map((uintptr_t)ram, sz >> EFI_PAGE_SHIFT,
> +                   EFI_CONVENTIONAL_MEMORY, false);
>      }
>
>  #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
> --------
>
> With that I'm at least getting further..  efi_allocate_pool()
> eventually fails, possibly making every small memory allocation page
> aligned means that 256m isn't enough..

Ok, still just as hacky, but works a bit better:

---------
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index cddafe2d43..b546b5e35d 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -14,6 +14,7 @@
 #include <linux/list_sort.h>
 #include <inttypes.h>
 #include <watchdog.h>
+#include <os.h>

 DECLARE_GLOBAL_DATA_PTR;

@@ -459,9 +460,9 @@ int efi_memory_init(void)
     unsigned long uboot_start, uboot_pages;
     unsigned long uboot_stack_size = 16 * 1024 * 1024;

-    efi_add_known_memory();
-
     if (!IS_ENABLED(CONFIG_SANDBOX)) {
+        efi_add_known_memory();
+
         /* Add U-Boot */
         uboot_start = (gd->start_addr_sp - uboot_stack_size) &
                 ~EFI_PAGE_MASK;
@@ -476,6 +477,14 @@ int efi_memory_init(void)
         runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
         efi_add_memory_map(runtime_start, runtime_pages,
                    EFI_RUNTIME_SERVICES_CODE, false);
+    } else {
+#define SZ_4K    0x00001000
+#define SZ_256M    0x10000000
+        size_t sz = SZ_256M;
+        uintptr_t ram = (uintptr_t)os_malloc(sz + SZ_4K) + SZ_4K;
+        efi_add_memory_map(ram & ~EFI_PAGE_MASK, sz >> EFI_PAGE_SHIFT,
+                   EFI_CONVENTIONAL_MEMORY, false);
+        gd->start_addr_sp = ~0;
     }

 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
---------

At this point it crashes in efi_load_pe() when it first tries to
dereference the address of the image passed in, ie. I'm running:

  host bind 0 x86_64-sct.img
  load host 0:1 0x01000000 /efi/boot/shell.efi
  bootefi 0x01000000

Not sure if there is a better way to pick an address to load into.  Or
maybe just assuming that PA==VA isn't a good idea in sandbox?

(Maybe being able to do 'bootefi host 0:1 /efi/boot/shell.efi' and
have bootefi take care or memory allocation for the loaded image would
be convenient)

BR,
-R


> BR,
> -R
>
>>> => bootefi selftest
>>>
>>> Testing EFI API implementation
>>>
>>> Number of tests to execute: 3
>>> <snip>
>>> Setting up 'ExitBootServices'
>>> Setting up 'ExitBootServices' succeeded
>>> Segmentation fault
>>> user at workstation:~/workspace/u-boot-odroid-c2/denx$
>>>
>>> The problem does not exist with qemu-x86_defconfig without your patches.
>>
>> fwiw, qemu-x86 still works for me (I can still load Shell.efi) with
>> these patches..
>>
>> BR,
>> -R
>>
>>> qemu-x86_defconfig cannot be built with you patches:
>>>
>>>   UPD     include/generated/asm-offsets.h
>>> sh: echo: I/O error
>>> Kbuild:47: recipe for target 'include/generated/generic-asm-offsets.h'
>>> failed
>>> make[1]: *** [include/generated/generic-asm-offsets.h] Error 1
>>> make[1]: *** Waiting for unfinished jobs....
>>> Makefile:1332: recipe for target 'prepare0' failed
>>> make: *** [prepare0] Error 2
>>>
>>> Best regards
>>>
>>> Heinrich


More information about the U-Boot mailing list