[U-Boot] [PATCH v2 2/2] efi_loader: rewrite README.efi

Alexander Graf agraf at suse.de
Fri Feb 9 18:55:45 UTC 2018



On 30.01.18 20:03, Heinrich Schuchardt wrote:
> Provide information about
> 
> - usage of the bootefi command
> - overview of UEFI
> - interaction between U-Boot and EFI drivers
> 
> Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
> ---
> v2
> 	new file

The patch is very hard to read. Please just make this 2 patches. One
that removes the old file, one that adds the rewrite.

> ---
>  doc/README.efi | 322 ++++++++++++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 264 insertions(+), 58 deletions(-)
> 
> diff --git a/doc/README.efi b/doc/README.efi
> index 956f5bfa0c..ea1facc431 100644
> --- a/doc/README.efi
> +++ b/doc/README.efi
> @@ -1,86 +1,292 @@
> -#
> -# Copyright (C) 2015 Google, Inc
> -#
> -# SPDX-License-Identifier:	GPL-2.0+
> -#
> +<!--
> +    Copyright (c) 2018 Heinrich Schuchardt
>  
> -EFI on U-Boot
> -=============
> -This document provides information about the implementation of the UEFI API [1]
> -in U-Boot.
> +    SPDX-License-Identifier:     GPL-2.0+
> +-->
>  
> +# EFI on U-Boot
>  
> -=========== Table of Contents ===========
> +## Motivation

Just remove the "Motivation" line. The text below is just the starting
paragraph for "EFI on U-Boot".

>  
> -Motivation
> -How do I get it?
> -Status
> -Future work
> +The Unified Extensible Firmware Interface Specification (UEFI) has become the
> +default for booting on AArch64 and x86 systems. It provides a stable API for the
> +interaction between the firmware and the drivers and applications loaded by the

firmware, drivers and applications

> +firmware. The API provides access to block storage, network, and console to name
> +a few. The Linux kernel and boot loaders like Grub or the FreeBSD loader can be
> +executed.
>  
> +## Building for EFI
>  
> -Motivation
> -----------
> +The UEFI standard supports only little endian systems. The EFI support can be
> +activated for ARM and x86 by specifying
>  
> -With this API support in place, you can run any UEFI payload (such as the Linux
> -kernel, grub2 or gummiboot) on U-Boot. This dramatically simplifies boot loader
> -configuration, as U-Boot based systems now look and feel (almost) the same way
> -as TianoCore based systems.
> +    CONFIG_CMD_BOOTEFI=y
> +    CONFIG_EFI_LOADER=y
>  
> -How do I get it?
> -----------------
> +in the .config file.
>  
> -EFI support for 32bit ARM and AArch64 is already included in U-Boot. All you
> -need to do is enable
> +Support for attaching virtual block devices, e.g. iSCSI drives connected by the
> +loaded EFI application, requires

Please provide a link to the README.iscsi file here.

>  
> -  CONFIG_CMD_BOOTEFI=y
> -  CONFIG_EFI_LOADER=y
> +    CONFIG_BLK=y
> +    CONFIG_PARTITIONS=y
>  
> -in your .config file and you will automatically get a bootefi command to run
> -an efi application as well as snippet in the default distro boot script that
> -scans for removable media efi binaries as fallback.
> +A hello world EFI application can be built with

All those hello world and selftest etc. things should be covered in
their own section IMHO. So you want to have a section on selftest (which
you have) and shortly mention the CONFIG option to enable it in there.

>  
> -Status
> -------
> +    CONFIG_CMD_BOOTEFI_HELLO_COMPILE=y
>  
> -I am successfully able to run grub2 and Linux EFI binaries with this code on
> -ARMv7 as well as AArch64 systems.
> +It can be embedded into the U-Boot binary for starting with command
> +'bootefi hello' with
>  
> -When enabled, the resulting U-Boot binary only grows by ~10KB, so it's very
> -light weight.
> +    CONFIG_CMD_BOOTEFI_HELLO=y
>  
> -All storage devices are directly accessible from the uEFI payload
> +A test suite that can be executed with command 'bootefi selftest' is provided
> +by
>  
> -Removable media booting (search for /efi/boot/boota{a64,arm}.efi) is supported.
> +    CONFIG_SELFTEST=y
>  
> -Simple use cases like "Plug this SD card into my ARM device and it just
> -boots into grub which boots into Linux", work very well.
> +## The bootefi command
>  
> +### Executing an EFI binary
>  
> -Running HelloWord.efi
> ----------------------
> +The bootefi command is used to start EFI applications or to install EFI drivers.
> +It takes two parameters
>  
> -You can run a simple 'hello world' EFI program in U-Boot.
> -Enable the option CONFIG_CMD_BOOTEFI_HELLO.
> +    bootefi <image address> [fdt address]
>  
> -Then you can boot into U-Boot and type:
> +* image address - the memory address of the EFI binary
> +* fdt address - the memory address of the flattened device tree
>  
> -   > bootefi hello
> +Below you find the output of an example session starting Grub.
>  
> -The 'hello world EFI' program will then run, print a message and exit.
> +    => load mmc 0:2 ${fdt_addr_r} boot/dtb
> +    29830 bytes read in 14 ms (2 MiB/s)
> +    => load mmc 0:1 ${kernel_addr_r} efi/debian/grubaa64.efi
> +    reading efi/debian/grubaa64.efi
> +    120832 bytes read in 7 ms (16.5 MiB/s)
> +    => bootefi ${kernel_addr_r} ${fdt_addr_r}
>  
> +The environment variable 'bootargs' is passed as load options in the EFI system
> +table. The Linux kernel EFI stub uses the load options as command line
> +arguments.
>  
> -Future work
> ------------
> +### Executing the boot manager
>  
> -Of course, there are still a few things one could do on top:
> +The UEFI specfication forsees to define boot entries and boot sequence via EFI
> +variables. Booting according to these variables is possible via
>  
> -   - 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
> -   - Payload Watchdog support
> +    bootefi bootmgr [fdt address]
>  
> -[1] http://uefi.org/
> +As of U-Boot v2018.03 EFI variables cannot be set by the operating system.

Depends on your scope of OS. This is a mine field to document correctly.
Just leave it out?

> So this development is not usable yet.

That's only half-true. Just remove the last sentence.

> +
> +### Executing the built in hello world application
> +

Here I would just mention that this depends on CONFIG_CMD_BOOTEFI_HELLO

> +For testing the bootefi command can be used to start a hello world application.
> +
> +    bootefi hello [fdt address]
> +
> +Below you find the output of an example session.
> +
> +    => bootefi hello
> +    ## Starting EFI application at 01000000 ...
> +    WARNING: Invalid device tree, expect boot to fail
> +    Hello, world!
> +    Have SMBIOS table
> +    Load options: root=/dev/sdb3 init=/sbin/init rootwait ro
> +    ## Application terminated, r = 0
> +
> +### Executing the built in hello world application

This does not describe the hello world application :). Same comment with
the CONFIG_ option applies here too.

> +
> +For testing the EFI implementation bootefi command can be used to start a self
> +test.
> +
> +    bootefi selftest [fdt address]
> +
> +The environment variable 'efi_selftest' can be used to select a single test. If
> +it is not provided all tests are executed except those marked as 'on request'.
> +If the environment variable is set to 'list' a list of all tests is shown.
> +
> +Below you find the output of an example session.
> +
> +    => setenv efi_selftest simple network protocol
> +    => bootefi selftest
> +    Testing EFI API implementation
> +    Selected test: 'simple network protocol'
> +    Setting up 'simple network protocol'
> +    Setting up 'simple network protocol' succeeded
> +    Executing 'simple network protocol'
> +    DHCP Discover
> +    DHCP reply received from 192.168.76.2 (52:55:c0:a8:4c:02)
> +      as broadcast message.
> +    Executing 'simple network protocol' succeeded
> +    Tearing down 'simple network protocol'
> +    Tearing down 'simple network protocol' succeeded
> +    Boot services terminated
> +    Summary: 0 failures
> +    Preparing for reset. Press any key.
> +
> +## The EFI life cycle
> +
> +After the U-Boot platform has been initialized the UEFI API provides two kinds
> +of services
> +
> +* boot services and
> +* runtime services.
> +
> +The API can be enhanced by loading EFI drivers which come in two variants

s/enhanced/extended/

> +
> +* boot drivers and
> +* runtime drivers.
> +
> +EFI drivers are installed with U-Boot's bootefi command. With the same command
> +EFI applications can be run.

s/run/executed/

> +
> +Loaded images of EFI drivers stay in memory after returning to U-Boot while
> +loaded images of applications are removed from memory.
> +
> +After an EFI application calls ExitBootServices

This is missing a sentence mentioning when someone would call
ExitBootServices.

> +
> +* boot services are not available anymore
> +* timer events are stopped
> +* the memory used by U-Boot except for runtime services is released
> +* the memory used by boot time drivers is released
> +
> +So this is the point of no return where the EFI application takes charge of the
> +system. Afterwards it can only return to U-Boot by rebooting.
> +
> +## The EFI object model
> +
> +EFI offers a flexible and expandable object model. The objects in the EFI API
> +are devices, drivers, and loaded images. These objects are referenced by
> +handles.
> +
> +The interfaces implemented by the objects are referred to as protocols. These
> +are identified by GUIDs. They can be installed and uninstalled by calling the
> +appropriate boot services.
> +
> +Handles are created by the InstallProtocolInterface or the
> +InstallMultipleProtocolinterfaces service if NULL is passed as handle.
> +
> +Handles are deleted when the last protocol has been removed with the
> +UninstallProtocolInterface or the UninstallMultipleProtocolInterfaces service.
> +
> +Devices offer the EFI_DEVICE_PATH_PROTOCOL. A device path is the concatenation
> +of device nodes. By their device paths all devices of a system are arranged in a
> +tree.
> +
> +Drivers offer the EFI_DRIVER_BINDING_PROTOCOL. This protocol is used to connect
> +a drivers to devices (which are referenced as controllers in this context).
> +
> +Loaded images offer the EFI_LOADED_IMAGE_PROTOCOL. This protocol provides meta
> +information about the image and the unload callback function.
> +
> +## The EFI events
> +
> +In the UEFI terminology an event is a data object referencing a notification
> +function which is queued for calling when the event is signaled. The following
> +types of events exist:
> +
> +* periodic and single shot timer events
> +* exit boot services events, triggered by calling the ExitBootServices() service
> +* virtual address change events (not yet implemented in U-Boot)
> +* events that are only triggered programmatically
> +
> +Events can be created with the CreateEvent service and deleted with CloseEvent
> +service.
> +
> +## The EFI driver model
> +
> +The device for which a driver is installed is called the controller.
> +
> +A driver is specific for a single protocol installed on a device. To install a
> +driver on a device the ConnectController service is called.
> +
> +The EFI_DRIVER_BINDING_PROTOCOL of the driver has three functions:
> +
> +* supported - determines if the driver is compatible with the device
> +* start - installs the driver by opening the relevant protocol with
> +  attribute EFI_OPEN_PROTOCOL_BY_DRIVER
> +* stop - uninstalls the driver
> +
> +The driver may create child controllers (child devices). E.g. a driver for block
> +IO devices will create the device handles for the partitions. The child
> +controllers  will open the supported protocol with attribute
> +EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
> +
> +A driver can be detached from a device with the DisconnectController service.
> +
> +## EFI uclass
> +
> +An EFI uclass driver (lib/efi_driver/efi_uclass.c) has been created that
> +maintains a list of all EFI drivers supplied by U-Boot. The uclass is
> +responsible for creating a handle for each of the drivers and installing and
> +handling the EFI_DRIVER_BINDING_PROTOCOL.

This is the one thing you can't read up in the UEFI specification, so
this is definitely a section that needs a good chunk of extension :).

> +
> +## U-Boot devices mapped as EFI devices
> +
> +Some of the U-Boot devices are mapped as EFI devices
> +
> +* block IO devices
> +* console
> +* graphical output
> +* network adapter
> +
> +As of U-Boot 2018.03 the logic for doing this is hard coded.
> +
> +The development target is to integrate the setup of these EFI devices with the
> +U-Boot driver model. So when an U-Boot device is discovered a handle should be

When you pronounce U-Boot, the first sound is a Y which is a consonant,
so you have to write "a U-Boot" :).

Yes, English is weird.

> +created and the device path protocol and the relevant IO protocol should be
> +installed. The EFI driver then would be attached by calling ConnectController.
> +When an U-Boot device is removed DisconnectController should be called.
> +
> +## EFI devices mapped as U-Boot devices

Ah, there is the section on the EFI_UCLASS. Please just move it into
this section and explain the *flow* that happens. Which entity creates
what when.

> +
> +EFI drivers and applications may create new (virtual) devices, install a
> +protocol and call the ConnectController service. Now the matching EFI driver can
> +be determined.
> +
> +It is the task of the EFI driver to create a corresponding U-Boot device and to
> +proxy calls for this U-Boot device to the controller.
> +
> +In U-Boot 2018.03 this has only been implemented for block IO devices.
> +
> +### EFI block IO driver
> +
> +The EFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL.
> +
> +When connected it creates a new U-Boot block IO device with interface type
> +IF_TYPE_EFI, adds child controllers mapping the partitions, and installs the
> +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the
> +software iPXE to boot from iSCSI network drives (see doc/README.iscsi).

Since you're using md syntax throughout, just use inter-file md links
here as well.

> +
> +The driver is only available if U-Boot is configured with
> +
> +    CONFIG_BLK=y
> +    CONFIG_PARTITIONS=y
> +
> +## Open issues as of U-Boot 2018.03
> +
> +* unimplemented or incompletely implemented boot services
> +** Exit - call unload function, unload applications only
> +** ReinstallProtocolInterface
> +** UnloadImage
> +
> +* unimplemented events
> +** EVT_RUNTIME
> +** EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
> +
> +* data model
> +** manage events in a linked list
> +** manage configuration tables in a linked list
> +
> +* EFI drivers
> +** support DisconnectController for EFI block devices.
> +
> +* Sandbox support for CONFIG_EFI_LOADER
> +
> +## Links
> +
> +http://uefi.org/specifications - UEFI specifications
> +doc/driver-model/README.txt - Driver model
> +doc/README.iscsi - iSCSI booting with U-Boot and iPXE

Mark them with md link tags and refer to them throughout the text when
you need it :)


Alex



More information about the U-Boot mailing list