On Fri, Mar 02, 2018 at 07:58:50PM +0100, Heinrich Schuchardt wrote: > Provides information about > > - usage of the bootefi command > - overview of UEFI > - interaction between U-Boot and EFI drivers > > Signed-off-by: Heinrich Schuchardt <xypron.g...@gmx.de>
Well, from my point of view: Reviewed-by: Leif Lindholm <leif.lindh...@linaro.org> or Acked-by: Leif Lindholm <leif.lindh...@linaro.org> (whichever makes more sense). Many thanks! / Leif > --- > v3 > rename README.efi to README.uefi > use UEFI instead of EFI where applicable > v2 > split the patch in two: one deleteing all old lines, the other > adding the new ones > update README contents > --- > MAINTAINERS | 2 +- > doc/README.efi | 0 > doc/README.uefi | 332 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 333 insertions(+), 1 deletion(-) > delete mode 100644 doc/README.efi > create mode 100644 doc/README.uefi > > diff --git a/MAINTAINERS b/MAINTAINERS > index 077828cf1d4..da799b551d9 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -290,7 +290,7 @@ EFI PAYLOAD > M: Alexander Graf <ag...@suse.de> > S: Maintained > T: git git://github.com/agraf/u-boot.git > -F: doc/README.efi > +F: doc/README.uefi > F: doc/README.iscsi > F: include/efi* > F: include/pe.h > diff --git a/doc/README.efi b/doc/README.efi > deleted file mode 100644 > index e69de29bb2d..00000000000 > diff --git a/doc/README.uefi b/doc/README.uefi > new file mode 100644 > index 00000000000..7403be36146 > --- /dev/null > +++ b/doc/README.uefi > @@ -0,0 +1,332 @@ > +<!-- > + Copyright (c) 2018 Heinrich Schuchardt > + > + SPDX-License-Identifier: GPL-2.0+ > +--> > + > +# UEFI on U-Boot > + > +The Unified Extensible Firmware Interface Specification (UEFI) [1] has become > +the default for booting on AArch64 and x86 systems. It provides a stable API > for > +the interaction of drivers and applications with the firmware. The API > comprises > +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 UEFI > + > +The UEFI standard supports only little endian systems. The UEFI support can > be > +activated for ARM and x86 by specifying > + > + CONFIG_CMD_BOOTEFI=y > + CONFIG_EFI_LOADER=y > + > +in the .config file. > + > +Support for attaching virtual block devices, e.g. iSCSI drives connected by > the > +loaded UEFI application [3], requires > + > + CONFIG_BLK=y > + CONFIG_PARTITIONS=y > + > +### Executing a UEFI binary > + > +The bootefi command is used to start UEFI applications or to install UEFI > +drivers. It takes two parameters > + > + bootefi <image address> [fdt address] > + > +* image address - the memory address of the UEFI binary > +* fdt address - the memory address of the flattened device tree > + > +Below you find the output of an example session starting GRUB. > + > + => 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 UEFI > system > +table. The Linux kernel EFI stub uses the load options as command line > +arguments. > + > +### Executing the boot manager > + > +The UEFI specfication foresees to define boot entries and boot sequence via > UEFI > +variables. Booting according to these variables is possible via > + > + bootefi bootmgr [fdt address] > + > +As of U-Boot v2018.03 UEFI variables are not persisted and cannot be set at > +runtime. > + > +### Executing the built in hello world application > + > +A hello world UEFI application can be built with > + > + CONFIG_CMD_BOOTEFI_HELLO_COMPILE=y > + > +It can be embedded into the U-Boot binary with > + > + CONFIG_CMD_BOOTEFI_HELLO=y > + > +The bootefi command is used to start the embedded hello world application. > + > + bootefi hello [fdt address] > + > +Below you find the output of an example session. > + > + => bootefi hello ${fdtcontroladdr} > + ## Starting EFI application at 01000000 ... > + WARNING: using memory device/image path, this may confuse some payloads! > + Hello, world! > + Running on UEFI 2.7 > + Have SMBIOS table > + Have device tree > + Load options: root=/dev/sdb3 init=/sbin/init rootwait ro > + ## Application terminated, r = 0 > + > +The environment variable fdtcontroladdr points to U-Boot's internal device > tree > +(if available). > + > +### Executing the built-in selftest > + > +An UEFI selftest suite can be embedded in U-Boot by building with > + > + CONFIG_CMD_BOOTEFI_SELFTEST=y > + > +For testing the UEFI implementation the bootefi command can be used to start > the > +selftest. > + > + 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 can 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 UEFI 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 extended by loading UEFI drivers which come in two variants > + > +* boot drivers and > +* runtime drivers. > + > +UEFI drivers are installed with U-Boot's bootefi command. With the same > command > +UEFI applications can be executed. > + > +Loaded images of UEFI drivers stay in memory after returning to U-Boot while > +loaded images of applications are removed from memory. > + > +An UEFI application (e.g. an operating system) that wants to take full > control > +of the system calls ExitBootServices. After a UEFI application calls > +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 a point of no return. Afterwards the UEFI application can only > return > +to U-Boot by rebooting. > + > +## The UEFI object model > + > +UEFI offers a flexible and expandable object model. The objects in the UEFI > 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 driver 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 a pointer to the unload callback function. > + > +## The UEFI 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 > +* memory map change events > +* read to boot events > +* reset system events > +* system table events > +* events that are only triggered programmatically > + > +Events can be created with the CreateEvent service and deleted with > CloseEvent > +service. > + > +Events can be assigned to an event group. If any of the events in a group is > +signaled, all other events in the group are also set to the signaled state. > + > +## The UEFI driver model > + > +A driver is specific for a single protocol installed on a device. To install > a > +driver on a device the ConnectController service is called. In this context > +controller refers to the device for which the driver is installed. > + > +The relevant drivers are identified using the EFI_DRIVER_BINDING_PROTOCOL. > This > +protocol has 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 the attribute > +EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. > + > +A driver can be detached from a device using the DisconnectController > service. > + > +## U-Boot devices mapped as UEFI devices > + > +Some of the U-Boot devices are mapped as UEFI 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 UEFI devices with > the > +U-Boot driver model. So when a U-Boot device is discovered a handle should be > +created and the device path protocol and the relevant IO protocol should be > +installed. The UEFI driver then would be attached by calling > ConnectController. > +When a U-Boot device is removed DisconnectController should be called. > + > +## UEFI devices mapped as U-Boot devices > + > +UEFI drivers binaries and applications may create new (virtual) devices, > install > +a protocol and call the ConnectController service. Now the matching UEFI > driver > +is determined by iterating over the implementations of the > +EFI_DRIVER_BINDING_PROTOCOL. > + > +It is the task of the UEFI 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. > + > +### UEFI uclass > + > +An UEFI uclass driver (lib/efi_driver/efi_uclass.c) has been created that > +takes care of initializing the UEFI drivers and providing the > +EFI_DRIVER_BINDING_PROTOCOL implementation for the UEFI drivers. > + > +A linker created list is used to keep track of the UEFI drivers. To create an > +entry in the list the UEFI driver uses the U_BOOT_DRIVER macro specifying > +UCLASS_EFI as the ID of its uclass, e.g. > + > + /* Identify as UEFI driver */ > + U_BOOT_DRIVER(efi_block) = { > + .name = "EFI block driver", > + .id = UCLASS_EFI, > + .ops = &driver_ops, > + }; > + > +The available operations are defined via the structure struct efi_driver_ops. > + > + struct efi_driver_ops { > + const efi_guid_t *protocol; > + const efi_guid_t *child_protocol; > + int (*bind)(efi_handle_t handle, void *interface); > + }; > + > +When the supported() function of the EFI_DRIVER_BINDING_PROTOCOL is called > the > +uclass checks if the protocol GUID matches the protocol GUID of the UEFI > driver. > +In the start() function the bind() function of the UEFI driver is called > after > +checking the GUID. > +The stop() function of the EFI_DRIVER_BINDING_PROTOCOL disconnects the child > +controllers created by the UEFI driver and the UEFI driver. (In U-Boot > v2013.03 > +this is not yet completely implemented.) > + > +### UEFI block IO driver > + > +The UEFI 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 [3]. > + > +This driver is only available if U-Boot is configured with > + > + CONFIG_BLK=y > + CONFIG_PARTITIONS=y > + > +## TODOs 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 > + * event groups > + > +* data model > + * manage events in a linked list > + * manage configuration tables in a linked list > + > +* UEFI drivers > + * support DisconnectController for UEFI block devices. > + > +* support for CONFIG_EFI_LOADER in the sandbox (CONFIG_SANDBOX=y) > + > +* UEFI variables > + * persistence > + * runtime support > + > +## Links > + > +* [1](http://uefi.org/specifications) > + http://uefi.org/specifications - UEFI specifications > +* [2](./driver-model/README.txt) doc/driver-model/README.txt - Driver model > +* [3](./README.iscsi) doc/README.iscsi - iSCSI booting with U-Boot and iPXE > -- > 2.16.1 > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot