[U-Boot] [PATCH 48/48] efi: Add a README to explain how things work

Bin Meng bmeng.cn at gmail.com
Fri Jul 24 11:12:14 CEST 2015


On Wed, Jul 22, 2015 at 11:49 PM, Simon Glass <sjg at chromium.org> wrote:
> Add some documentation on the EFI implementation in U-Boot.
>
> Signed-off-by: Ben Stoltz <stoltz at google.com>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>

Well written doc!

Reviewed-by: Bin Meng <bmeng.cn at gmail.com>

But please check nits below.

>  doc/README.efi | 237 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 237 insertions(+)
>  create mode 100644 doc/README.efi
>
> diff --git a/doc/README.efi b/doc/README.efi
> new file mode 100644
> index 0000000..4706602
> --- /dev/null
> +++ b/doc/README.efi
> @@ -0,0 +1,237 @@
> +#
> +# Copyright (C) 2015 Google, Inc
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +U-Boot on EFI
> +=============
> +This document provides information about U-Boot running on top of EFI, either
> +as an application or just as a means of getting U-Boot onto a new platform.
> +
> +
> +In God's Name, Why?
> +-------------------
> +This is useful in several situations:
> +
> +- You have EFI running on a board but U-Boot does not natively support it
> +fully yet. You can boot into U-Boot from EFI and use that until U-Boot is
> +fully ported
> +
> +- You need to use an EFI implementation (e.g. UEFI) because your vendor
> +requires it in order to provide support
> +
> +- You plan to use Coreboot to boot into U-Boot but Coreboot support does

coreboot

> +not currently exist for your platform. In the meantime you can use U-Boot
> +on EFI and then move to U-Boot on Coreboot when ready

coreboot

> +
> +- You use EFI but want to experiment with a simpler alternative like U-Boot
> +
> +
> +Status
> +------
> +Only x86 is supported at present. If you are using EFI on another
> +architecture you may want to reconsider. However, much of the code is generic

Can we move 'architecture' one line above, or will it exceed the 80
char limitation?

> +so could be ported.
> +
> +U-Boot supports running as an EFI application for 32-bit EFI only. This is
> +not very useful since only a serial port is provided. You can look around at
> +memory and type 'help' but that is about it.
> +
> +More usefully, U-Boot supports building itself as a payload for either 32-bit
> +or 64-bit EFI. U-Boot is packaged up and loaded in its entirety by EFI. Once
> +started, U-Boot changes to 32-bit mode (currently) and takes over the
> +machine. You can use devices, boot a kernel, etc.
> +
> +
> +Build Instructions
> +------------------
> +First choose a board that has EFI support and obtain an EFI implementation
> +for that board. It will be either 32-bit or 64-bit.
> +
> +To build U-Boot as an EFI application (32-bit EFI required), enable
> +CONFIG_EFI and CONFIG_ARCH_EFI. The efi-x86 config is set up for this.

CONFIG_ARCH_EFI, see my previous comments.

> +
> +To build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), adjust
> +an existing config to enable CONFIG_EFI, CONFIG_EFI_STUB and either
> +CONFIG_EFI_STUB_32BIT or CONFIG_EFI_STUB_64BIT.
> +
> +Then build U-Boot as normal, e.g.
> +
> +   make qemu-x86_defconfig
> +   make menuconfig    (or make xconfig if you prefer)
> +   # change the settings as above
> +   make
> +
> +You will end up with one of these files:
> +
> +   u-boot.efi          - U-Boot EFI application

u-boot-app.efi, see my previous comments.

> +   u-boot-payload.efi  - U-Boot EFI payload application
> +
> +
> +Trying it out
> +-------------
> +Qemu is an emulator and it can emulate an x86 machine. You can run the
> +payload with something like this:
> +
> +   mkdir /tmp/efi
> +   cp /path/to/u-boot*.efi /tmp/efi
> +   qemu-system-x86_64 -bios bios.bin -hda fat:/tmp/efi/
> +
> +Add -nographic if you want to use the terminal for output. Once it starts
> +type 'fs0:u-boot-payload.efi' to run the payload or 'fs0:u-boot.efi' to run
> +the application. 'bios.bin' is the EFI 'BIOS'.
> +
> +To try it on real hardware, put u-boot.efi on a suitable boot medium, such
> +as a USB stick. Then you can type something like this to start it:
> +
> +   fs0:u-boot-payload.efi
> +
> +(or fs0:u-boot.efi for the application)
> +
> +This will start the payload, copy U-Boot into RAM and start U-Boot. Note
> +that EFI does not support booting a 64-bit application from a 32-bit
> +EFI (or vice versa). Also it will often fail to print an error message if
> +you get this wrong.
> +
> +
> +Inner workings
> +==============
> +Here follow a few implementation notes for those who want to fiddle with
> +this and perhaps contribute patches.
> +
> +The application and payload approaches sound similar but are in fact
> +implemented completely differently.
> +
> +EFI Application
> +---------------
> +For the application the whole of U-Boot is built as a shared library. The
> +efi_main() function is in lib/efi/efi_app.c. It sets up some basic EFI
> +functions with efi_init(), sets up U-Boot global_data, allocates memory for
> +U-Boot's malloc(), etc. and enters the normal init sequence (board_init_f()
> +and board_init_r()).
> +
> +Since U-Boot limits its memory access to the allocated regions very little
> +special code is needed. The CONFIG_ARCH_EFI option controls a few things
> +that need to change so 'git grep CONFIG_ARCH_EFI' may be instructive.
> +The CONFIG_EFI option controls more general EFI adjustments.
> +
> +The only available driver is the serial driver. This calls back into EFI
> +'boot services' to send and receive characters. Although it is implemented
> +as a serial driver the console device is not necessarilly serial. If you
> +boot EFI with video output then the 'serial' device will operate on your
> +target devices's display instead and the device's USB keyboard will also
> +work if connected. If you have both serial and video output, then both
> +consoles will be active. Even though U-Boot does the same thing normally,
> +These are features of EFI, not U-Boot.
> +
> +Very little code is involved in implementing the EFI application feature.
> +U-Boot is highly portable. Most of the difficulty is in modifying the
> +Makefile settings to pass the right build flags. In particular there is very
> +little x86-specific code involved - you can find most of it in
> +arch/x86/cpu. Porting to ARM (which can also use EFI if you are brave
> +enough) should be straightforward.
> +
> +Use the 'reset' command to get back to EFI.
> +
> +EFI Payload
> +-----------
> +The payload approach is a different kettle of fish. It works by building
> +U-Boot exactly as normal for your target board, then adding the entire
> +image (including device tree) into a small EFI stub application responsible
> +for booting it. The stub application is built as a normal EFI application
> +except that it has a lot of data attached to it.
> +
> +The stub application is implemented in lib/efi/efi_stub.c. The efi_main()
> +function is called by EFI. It is responsible for copying U-Boot from its
> +original location into memory, disabling EFI boot services and starting
> +U-Boot. U-Boot then starts as normal, relocates, starts all drivers, etc.
> +
> +The stub application is architecture-dependent. At present it has some
> +x86-specific code and a comment at the top of efi_stub.c describes this.
> +
> +While the stub application does allocate some memory from EFI this is not
> +used by U-Boot (the payload). In fact when U-Boot starts it has all of the
> +memory available to it and can operate as it pleases (but see the next
> +section).
> +
> +Tables
> +------
> +The payload can pass information to U-Boot in the form of EFI tables. At
> +present this feature is used to pass the EFI memory map, an inordinately
> +large list of memory regions. You can use the 'efi mem all' command to
> +display this list. U-Boot uses the list to work out where to relocate
> +itself.
> +
> +Although U-Boot can use any memory it likes, EFI marks some memory as used
> +by 'run-time services', code that hangs around while U-Boot is running and
> +is even present when Linux is running. This is common on x86 and provides
> +a way for Linux to call back into the firmware to control things like CPU
> +fan speed. U-Boot uses only 'conventional' memory, in EFI terminology. It
> +will relocate itself to the top of the largest block of memory it can find
> +below 4GB.
> +
> +Interrupts
> +----------
> +U-Boot drivers typically don't use interrupts. Since EFI enables interrupts
> +it is possible that an interrupt will fire that U-Boot cannot handle. This
> +seems to cause problems. For this reason the U-Boot payload runs with
> +interrupts disabled at present.
> +
> +32/64-bit
> +---------
> +While the EFI application can in principle be built as either 32- or 64-bit,
> +only 32-bit is currently supported. This means that the application can only
> +be used with 32-bit EFI.
> +
> +The payload stub can be build as either 32- or 64-bits. Only a small amount
> +of code is built this way (see the extra- line in lib/efi/Makefile).
> +Everything else is built as a normal U-Boot, so is always 32-bit on x86 at
> +present.
> +
> +Future work
> +-----------
> +This work could be extended in a number of ways:
> +
> +- Add a generic x86 EFI payload configuration. At present you need to modify
> +an existing one, but mostly the low-level x86 code is disabled when booting
> +on EFI anyway, so a generic 'EFI' board could be created with a suitable set
> +of drivers enabled.
> +
> +- Add ARM support
> +
> +- Add 64-bit application support
> +
> +- Figure out how to solve the interrupt problem
> +
> +- Add more drivers to the application side (e.g. video, block devices, USB,
> +environment access). This would mostly be an academic exercise as a strong
> +use case is not readily apparent, but it might be fun.
> +
> +- Avoid turning off boot services in the stub. Instead allow U-Boot to make
> +use of boot services in case it wants to. It is unclear what it might want
> +though.
> +
> +Where is the code?
> +------------------
> +lib/efi
> +       payload stub, application, support code. Mostly arch-neutral
> +
> +arch/x86/lib/efi
> +       helper functions for the fake DRAM init, etc. These can be used by
> +       any board that runs as a payload.
> +
> +arch/x86/cpu/efi
> +       x86 support code for running as an EFI application
> +
> +board/efi/efi-x86/efi.c
> +       x86 board code for running as an EFI application
> +
> +common/cmd_efi.c
> +       the 'efi' command
> +
> +
> +--
> +Ben Stoltz, Simon Glass
> +Google, Inc
> +July 2015
> --

Regards,
Bin


More information about the U-Boot mailing list