5. Services - Boot Services

5.1. Extensions to UEFI Boot Service Event Usage

5.1.1. CreateEvent

CreateEventEx() in UEFI 2.0 allows for registration of events named by GUID’s. The DXE foundation defines the following:

#define EFI_EVENT_LEGACY_BOOT_GUID
  {0x2a571201, 0x4966, 0x47f6, 0x8b, 0x86, 0xf3, 0x1e,
  0x41, 0xf3, 0x2f, 0x10}

This event is to be used with CreateEventEx() in order to be notified when the UEFI boot manager is about to boot a legacy boot option. Notification of events of this type is sent just before Int19h is invoked.

5.1.2. Pre-Defined Event Groups

This section describes the pre-defined event groups used by this specification.

EFI_EVENT_GROUP_DXE_DISPATCH_GUID

This event group is notified by the system when the DXE dispatcher finished one round of driver dispatch. This allows the SMM dispatcher get chance to dispatch SMM driver which will depend on UEFI protocols.

#define EFI_EVENT_GROUP_DXE_DISPATCH_GUID \
  { 0x7081e22f, 0xcac6, 0x4053, { 0x94, 0x68, 0x67, 0x57, \
  0x82, 0xcf, 0x88, 0xe5 } \ }

5.1.2.1. End of DXE Event

Prior to invoking any UEFI drivers, or applications that are not from the platform manufacturer, or connecting consoles, the platform should signals the event EFI_END_OF_DXE_EVENT_GUID End of DXE Event and immediately after that the platform installs DXE SMM Ready to Lock Protocol (defined in volume 4).

#define EFI_END_OF_DXE_EVENT_GROUP_GUID \
  { 0x2ce967a, 0xdd7e, 0x4ffc, { 0x9e, 0xe7, 0x81, 0xc, \
  0xf0, 0x47, 0x8, 0x80 } }

From SEC through the signaling of this event, all of the components should be under the authority of the platform manufacturer and not have to worry about interaction or corruption by 3rd party extensible modules such as UEFI drivers and UEFI applications.

Platform may choose to lock certain resources or disable certain interfaces prior to executing third party extensible modules. Transition from the environment where all of the components are under the authority of the platform manufacturer to the environment where third party modules are executed is a two-step process:

  1. End of DXE Event is signaled. This event presents the last opportunity to use resources or interfaces that are going to be locked or disabled in anticipation of the invocation of 3rd party extensible modules.

  2. DXE SMM Ready to Lock Protocol is installed. PI modules that need to lock or protect their resources in anticipation of the invocation of 3rd party extensible modules should register for notification on installation of this protocol and effect the appropriate protections in their notification handlers

5.1.3. Additions to LoadImage()

Summary

Loads an UEFI image into memory. This function has been extended from the LoadImage() Boot Service defined in the UEFI 2.0 specification. The DXE foundation extends this to support an additional image type, allowing UEFI images to be loaded from files stored in firmware volumes. It also validates the image using the services of the Security Architectural Protocol.

Prototype

EFI_STATUS
LoadImage (
  IN BOOLEAN          BootPolicy,
  IN EFI_HANDLE       ParentImageHandle,
  IN EFI_DEVICE_PATH  *FilePath,
  IN VOID             *SourceBuffer OPTIONAL ,
  IN UINTN            SourceSize,
  OUT EFI_HANDLE      *ImageHandle
  );

Parameters

BootPolicy

If TRUE , indicates that the request originates from the boot manager, and that the boot manager is attempting to load FilePath as a boot selection. Ignored if SourceBuffer is not NULL .

ParentImageHandle

The caller’s image handle. Type EFI_HANDLE is defined in the InstallProtocolInterface() function description in the UEFI 2.0 specification. This field is used to initialize the ParentHandle field of the LOADED_IMAGE protocol for the image that is being loaded.

FilePath

The specific file path from which the image is loaded. Type EFI_DEVICE_PATH is defined in the LocateDevicePath() function description in the UEFI 2.0 specification.

SourceBuffer

If not NULL , a pointer to the memory location containing a copy of the image to be loaded.

SourceSize

The size in bytes of SourceBuffer . Ignored if SourceBuffer is NULL .

ImageHandle

Pointer to the returned image handle that is created when the image is successfully loaded. Type EFI_HANDLE is defined in the InstallProtocolInterface() function description in the UEFI 2.0 specification.

Description

The LoadImage() function loads an UEFI image into memory and returns a handle to the image. The supported subsystem values in the PE image header are listed in “Related Definitions” below. The image is loaded in one of two ways. If SourceBuffer is not NULL , the function is a memory-to-memory load in which SourceBuffer points to the image to be loaded and SourceSize indicates the image’s size in bytes. FilePath specifies where the image specified by SourceBuffer and SourceSize was loaded. In this case, the caller has copied the image into SourceBuffer and can free the buffer once loading is complete.

If SourceBuffer is NULL , the function is a file copy operation that uses the EFI_FIRMWARE_VOLUME2_PROTOCOL , followed by the SIMPLE_FILE_SYSTEM_PROTOCOL and then the LOAD_FILE_PROTOCOL to access the file referred to by FilePath . In this case, the BootPolicy flag is passed to the LOAD_FILE.LoadFile() function and is used to load the default image responsible for booting when the FilePath only indicates the device. For more information see the discussion of the Load File Protocol in Chapter 11 of the UEFI 2.0 specification.

Regardless of the type of load (memory-to-memory or file copy), the function relocates the code in the image while loading it.

The image is also validated using the FileAuthenticationState() service of the Security Architectural Protocol (SAP). If the SAP returns the status EFI_SUCCESS , then the load operation is completed normally. If the SAP returns the status EFI_SECURITY_VIOLATION , then the load operation is completed normally, and the EFI_SECURITY_VIOLATION status is returned. In this case, the caller is not allowed to start the image until some platform specific policy is executed to protect the system while executing untrusted code. If the SAP returns the status EFI_ACCESS_DENIED , then the image should never be trusted. In this case, the image is unloaded from memory, and EFI_ACCESS_DENIED is returned.

Once the image is loaded, firmware creates and returns an EFI_HANDLE that identifies the image and supports the LOADED_IMAGE_PROTOCOL . The caller may fill in the image’s “load options” data, or add additional protocol support to the handle before passing control to the newly loaded image by calling StartImage() . Also, once the image is loaded, the caller either starts it by calling StartImage() or unloads it by calling UnloadImage() .

//**********************************************************
// Supported subsystem values
//**********************************************************


#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION         10
#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER      12
#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER      13

Supported Subsystem Values describes the fields in the above definition.

Table 5.10 Supported Subsystem Values

Supported Subsystem Values

Description

EFI_IMAGE_SUBSYSTEM_EFI _APPLICATION

The image is loaded into memory of type EfiLoaderCode , and the memory is freed when the application exits

EFI_IMAGE_SUBSYSTEM_EFI _BOOT_SERVICE_DRIVER

The image is loaded into memory of type EfiBootServicesCode . If the image exits with an error code, then the memory for the image is free. If the image exits with EFI_SUCCESS , then the memory for the image is not freed.

EFI_IMAGE_SUBSYSTEM_EFI _RUNTIME_DRIVER

The image is loaded intoThe image is loaded into memory of type EfiRuntimeServicesCode . If the image exits with an error code, then the memory for the image is free. If the image exits with EFI_SUCCESS , then the memory for the image is not freed. Images of this type are automatically converted from physical addresses to virtual address when the Runtime Service SetVirtualAddressMap() is called.

EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER

The image is loaded intoThe image is loaded into memory of type EfiRuntimeServicesCode . If the image exits with an error code, then the memory for the image is free. If the image exits with EFI_SUCCESS , then the memory for the image is not freed. Images of this type are not converted from physical addresses to virtual address when the Runtime Service SetVirtualAddressMap() is called.

Status Codes Returned

Table 5.11 Status Codes Returned

EFI_SUCCESS

The image was loaded into memory

EFI_SECURITY_VIOLATION

The image was loaded into memory but the current security policy dictates that the image should not be executed at this time

EFI_ACCESS_DENIED

The image was not loaded into memory because the current security policy dictates that the image should never be executed

EFI_NOT_FOUND

The FilePath was not found

EFI_INVALID_PARAMETER

One of the parameters has an invalid value

EFI_UNSUPPORTED

The image type is not supported or the device path cannot be parsed to locate the proper protocol for loading the file

EFI_OUT_OF_RESOURCES

Image was not loaded due to insufficient resources

EFI_LOAD_ERROR

Image was not loaded because the image format was corrupt or not understood

EFI_DEVICE_ERROR

Image was not loaded because the device returned a read error