[U-Boot] [PATCH 00/14] EFI payload / application support v2

Alexander Graf
2016-01-15T05:06:06Z

This is my Christmas present for my openSUSE friends :).

U-Boot is a great project for embedded devices. However, convincing
everyone involved that only for "a few oddball ARM devices" we need to
support different configuration formats from grub2 when all other platforms
(PPC, System Z, x86) are standardized on a single format is a nightmare.

So we started to explore alternatives. At first, people tried to get
grub2 running using the u-boot api interface. However, FWIW that one
doesn't support relocations, so you need to know where to link grub2 to
at compile time. It also seems to be broken more often than not. And on
top of it all, it's a one-off interface, so yet another thing to maintain.

That led to a nifty idea. What if we can just implement the EFI application
protocol on top of U-Boot? Then we could compile a single grub2 binary for
uEFI based systems and U-Boot based systems and as soon as that one's loaded,
everything looks and feels (almost) the same.

This patch set is the result of pursuing this endeavor.

- I am successfully able to run grub2 and Linux EFI binaries with this code.
- When enabled, the resulting U-Boot binary only grows by ~10kb,
so it's very light weight.
- It works on 32bit ARM and AArch64.
- All storage devices are directly accessible
- No EFI variables
- Removable media booting (search for /efi/boot/boota{a64,arm}.efi)

Of course, there are still a few things one could do on top:

- Improve disk media detection (don't scan, use what information we have)
- Add EFI variable support using NVRAM
- Add GFX support
- Make EFI Shell work ;)
- Network device support
- Support for payload exit

But so far, I'm very happy with the state of the patches. They completely
eliminate potential arguments against U-Boot internally and give users the
chance to run with the same level of comfort on all firmware types.

Version 2 was successfully tested to boot grub2 and Linux from there on a
HiKey (AArch64, dcache disabled) and on a BeagleBone Black.

If you read this far and want to try out the patches, feel free to grab
the source from git at:

https://github.com/agraf/u-boot efi-v2

or just use the readily compiled version from

https://build.opensuse.org/project/show/home:algraf:branches:Base:System

v1 -> v2:
- move memory allocation to separate patch
- limit 32/64 to hosts that support it
- check 32bit optional nt header magic
- switch to GPLv2+
- Fix typo s/does now/does not/
- Add #ifdefs around header to allow inclusion when efi_loader is disabled
- Add stub efi_restore_gd() function when efi_loader is disabled
- Disable debug
- Mark runtime region as such
- Fix up memory map
- Allow efi_restore_gd to be called before first efi entry
- Add 32bit arm cache workaround
- Move memory map to separate patch
- Change BTS version to 2.5
- Fix return values for a few callbacks to more EFI compliant ones
- Change vendor to "Das U-Boot"
- Add warning when truncating timer trigger
- Add runtime detach
- Enable runtime relocations
- Add get_time
- Fix relocation
- Fix 32bit
- Add am335x support
- Move section definition to header
- Add systab to runtime section
- Add self-relocation hook table
- Relocate efi_runtime section early during bootup
- Fix return values for a number of callbacks to be more UEFI compliant
- Move to block_drvr array
- Fix header order
- Document efi block object struct
- Use calloc rather than malloc & memset
- Default to y
- New patches:
- disk/part.c: Expose list of available block drivers
- arm64: Allow exceptions to return
- arm64: Allow EFI payload code to take exceptions
- efi_loader: Add DCACHE_OFF support for arm64
- efi_loader: Add distro boot script for removable media

Alex

Alexander Graf (14):
disk/part.c: Expose list of available block drivers
include/efi_api.h: Add more detailed API definitions
efi_loader: Add PE image loader
efi_loader: Add boot time services
efi_loader: Add console interface
efi_loader: Add runtime services
efi_loader: Add disk interfaces
efi_loader: Add "bootefi" command
efi_loader: Implement memory allocation and map
arm64: Allow exceptions to return
arm64: Allow EFI payload code to take exceptions
efi_loader: Add DCACHE_OFF support for arm64
efi_loader: hook up in build environment
efi_loader: Add distro boot script for removable media

arch/arm/config.mk | 4 +
arch/arm/cpu/armv8/exceptions.S | 44 ++
arch/arm/cpu/armv8/u-boot.lds | 16 +
arch/arm/cpu/u-boot.lds | 30 ++
arch/arm/lib/Makefile | 3 +
arch/arm/lib/interrupts_64.c | 28 ++
arch/arm/lib/sections.c | 4 +
arch/arm/lib/unaligned_64.c | 284 +++++++++++++
board/ti/am335x/u-boot.lds | 30 ++
common/Makefile | 1 +
common/board_r.c | 4 +
common/cmd_bootefi.c | 159 +++++++
disk/part.c | 7 +-
include/config_distro_bootcmd.h | 47 ++-
include/efi_api.h | 197 +++++++--
include/efi_loader.h | 90 ++++
include/part.h | 8 +
include/pe.h | 263 ++++++++++++
lib/Kconfig | 1 +
lib/Makefile | 1 +
lib/efi_loader/Kconfig | 9 +
lib/efi_loader/Makefile | 11 +
lib/efi_loader/efi_boottime.c | 856 ++++++++++++++++++++++++++++++++++++++
lib/efi_loader/efi_console.c | 357 ++++++++++++++++
lib/efi_loader/efi_disk.c | 218 ++++++++++
lib/efi_loader/efi_image_loader.c | 202 +++++++++
lib/efi_loader/efi_runtime.c | 300 +++++++++++++
27 files changed, 3130 insertions(+), 44 deletions(-)
create mode 100644 arch/arm/lib/unaligned_64.c
create mode 100644 common/cmd_bootefi.c
create mode 100644 include/efi_loader.h
create mode 100644 include/pe.h
create mode 100644 lib/efi_loader/Kconfig
create mode 100644 lib/efi_loader/Makefile
create mode 100644 lib/efi_loader/efi_boottime.c
create mode 100644 lib/efi_loader/efi_console.c
create mode 100644 lib/efi_loader/efi_disk.c
create mode 100644 lib/efi_loader/efi_image_loader.c
create mode 100644 lib/efi_loader/efi_runtime.c

--
2.1.4