mirror of https://github.com/acidanthera/audk.git
MdeModulePkg: Process Sys Prep load options in BdsDxe driver.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Eric Dong <eric.dong@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17403 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
573b8a86d0
commit
1634214dbb
|
@ -27,8 +27,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
// Load Option Type
|
||||
//
|
||||
typedef enum {
|
||||
LoadOptionTypeBoot,
|
||||
LoadOptionTypeDriver,
|
||||
LoadOptionTypeSysPrep,
|
||||
LoadOptionTypeBoot,
|
||||
LoadOptionTypeMax
|
||||
} EFI_BOOT_MANAGER_LOAD_OPTION_TYPE;
|
||||
|
||||
|
@ -51,6 +52,7 @@ typedef struct {
|
|||
EFI_DEVICE_PATH_PROTOCOL *FilePath; // Load Option Device Path
|
||||
UINT8 *OptionalData; // Load Option optional data to pass into image
|
||||
UINT32 OptionalDataSize; // Load Option size of OptionalData
|
||||
EFI_GUID VendorGuid;
|
||||
|
||||
//
|
||||
// Used at runtime
|
||||
|
@ -172,11 +174,11 @@ EfiBootManagerLoadOptionToVariable (
|
|||
);
|
||||
|
||||
/**
|
||||
This function will update the Boot####/Driver#### and the BootOrder/DriverOrder
|
||||
to add a new load option.
|
||||
This function will update the Boot####/Driver####/SysPrep#### and the
|
||||
BootOrder/DriverOrder/SysPrepOrder to add a new load option.
|
||||
|
||||
@param Option Pointer to load option to add.
|
||||
@param Position Position of the new load option to put in the BootOrder/DriverOrder.
|
||||
@param Position Position of the new load option to put in the BootOrder/DriverOrder/SysPrepOrder.
|
||||
|
||||
@retval EFI_SUCCESS The load option has been successfully added.
|
||||
@retval Others Error status returned by RT->SetVariable.
|
||||
|
@ -458,17 +460,20 @@ EfiBootManagerConnectAll (
|
|||
/**
|
||||
This function will create all handles associate with every device
|
||||
path node. If the handle associate with one device path node can not
|
||||
be created successfully, then still give one chance to do the dispatch,
|
||||
be created successfully, then still give chance to do the dispatch,
|
||||
which load the missing drivers if possible.
|
||||
|
||||
@param DevicePathToConnect The device path which will be connected, it CANNOT be
|
||||
@param DevicePathToConnect The device path which will be connected, it can be
|
||||
a multi-instance device path
|
||||
@param MatchingHandle Return the controller handle closest to the DevicePathToConnect
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DevicePathToConnect is NULL.
|
||||
@retval EFI_NOT_FOUND Failed to create all handles associate with every device path node.
|
||||
@retval EFI_SUCCESS Successful to create all handles associate with every device path node.
|
||||
|
||||
@retval EFI_SUCCESS All handles associate with every device path node
|
||||
have been created.
|
||||
@retval EFI_OUT_OF_RESOURCES There is no resource to create new handles.
|
||||
@retval EFI_NOT_FOUND Create the handle associate with one device path
|
||||
node failed.
|
||||
@retval EFI_SECURITY_VIOLATION The user has no permission to start UEFI device
|
||||
drivers on the DevicePath.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
|
@ -508,8 +513,12 @@ typedef enum {
|
|||
/**
|
||||
This function will connect all the console devices base on the console
|
||||
device variable ConIn, ConOut and ErrOut.
|
||||
|
||||
@retval EFI_DEVICE_ERROR All the consoles were not connected due to an error.
|
||||
@retval EFI_SUCCESS Success connect any one instance of the console
|
||||
device path base on the variable ConVarName.
|
||||
**/
|
||||
VOID
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiBootManagerConnectAllDefaultConsoles (
|
||||
VOID
|
||||
|
@ -654,4 +663,19 @@ EfiBootManagerFreeDriverHealthInfo (
|
|||
UINTN Count
|
||||
);
|
||||
|
||||
/**
|
||||
Process (load and execute) the load option.
|
||||
|
||||
@param LoadOption Pointer to the load option.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER The load option type is invalid,
|
||||
or the load option file path doesn't point to a valid file.
|
||||
@retval EFI_UNSUPPORTED The load option type is of LoadOptionTypeBoot.
|
||||
@retval EFI_SUCCESS The load option is inactive, or successfully loaded and executed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiBootManagerProcessLoadOption (
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption
|
||||
);
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -102,12 +102,13 @@ EfiBootManagerConnectAll (
|
|||
a multi-instance device path
|
||||
@param MatchingHandle Return the controller handle closest to the DevicePathToConnect
|
||||
|
||||
@retval EFI_SUCCESS All handles associate with every device path node
|
||||
have been created
|
||||
@retval EFI_OUT_OF_RESOURCES There is no resource to create new handles
|
||||
@retval EFI_NOT_FOUND Create the handle associate with one device path
|
||||
node failed
|
||||
|
||||
@retval EFI_SUCCESS All handles associate with every device path node
|
||||
have been created.
|
||||
@retval EFI_OUT_OF_RESOURCES There is no resource to create new handles.
|
||||
@retval EFI_NOT_FOUND Create the handle associate with one device path
|
||||
node failed.
|
||||
@retval EFI_SECURITY_VIOLATION The user has no permission to start UEFI device
|
||||
drivers on the DevicePath.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
|
@ -166,9 +167,8 @@ EfiBootManagerConnectDevicePath (
|
|||
// Connect all drivers that apply to Handle and RemainingDevicePath,
|
||||
// the Recursive flag is FALSE so only one level will be expanded.
|
||||
//
|
||||
// Do not check the connect status here, if the connect controller fail,
|
||||
// then still give the chance to do dispatch, because partial
|
||||
// RemainingDevicepath may be in the new FV
|
||||
// If ConnectController fails to find a driver, then still give the chance to
|
||||
// do dispatch, because partial RemainingDevicePath may be in the new FV
|
||||
//
|
||||
// 1. If the connect fail, RemainingDevicepath and handle will not
|
||||
// change, so next time will do the dispatch, then dispatch's status
|
||||
|
@ -177,7 +177,10 @@ EfiBootManagerConnectDevicePath (
|
|||
// change, then avoid the dispatch, we have chance to continue the
|
||||
// next connection
|
||||
//
|
||||
gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
|
||||
Status = gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
|
||||
if (Status == EFI_NOT_FOUND) {
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
if (MatchingHandle != NULL) {
|
||||
*MatchingHandle = Handle;
|
||||
}
|
||||
|
|
|
@ -695,28 +695,42 @@ EfiBootManagerConnectAllConsoles (
|
|||
/**
|
||||
This function will connect all the console devices base on the console
|
||||
device variable ConIn, ConOut and ErrOut.
|
||||
|
||||
@retval EFI_DEVICE_ERROR All the consoles were not connected due to an error.
|
||||
@retval EFI_SUCCESS Success connect any one instance of the console
|
||||
device path base on the variable ConVarName.
|
||||
**/
|
||||
VOID
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiBootManagerConnectAllDefaultConsoles (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN OneConnected;
|
||||
BOOLEAN SystemTableUpdated;
|
||||
|
||||
EfiBootManagerConnectConsoleVariable (ConOut);
|
||||
OneConnected = FALSE;
|
||||
|
||||
Status = EfiBootManagerConnectConsoleVariable (ConOut);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
OneConnected = TRUE;
|
||||
}
|
||||
PERF_START (NULL, "ConOutReady", "BDS", 1);
|
||||
PERF_END (NULL, "ConOutReady", "BDS", 0);
|
||||
|
||||
|
||||
EfiBootManagerConnectConsoleVariable (ConIn);
|
||||
Status = EfiBootManagerConnectConsoleVariable (ConIn);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
OneConnected = TRUE;
|
||||
}
|
||||
PERF_START (NULL, "ConInReady", "BDS", 1);
|
||||
PERF_END (NULL, "ConInReady", "BDS", 0);
|
||||
|
||||
//
|
||||
// The _ModuleEntryPoint err out var is legal.
|
||||
//
|
||||
EfiBootManagerConnectConsoleVariable (ErrOut);
|
||||
Status = EfiBootManagerConnectConsoleVariable (ErrOut);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
OneConnected = TRUE;
|
||||
}
|
||||
PERF_START (NULL, "ErrOutReady", "BDS", 1);
|
||||
PERF_END (NULL, "ErrOutReady", "BDS", 0);
|
||||
|
||||
|
@ -745,4 +759,6 @@ EfiBootManagerConnectAllDefaultConsoles (
|
|||
&gST->Hdr.CRC32
|
||||
);
|
||||
}
|
||||
|
||||
return OneConnected ? EFI_SUCCESS : EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -120,146 +120,6 @@ BmMatchDevicePaths (
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the headers (dos, image, optional header) from an image
|
||||
|
||||
@param Device SimpleFileSystem device handle
|
||||
@param FileName File name for the image
|
||||
@param DosHeader Pointer to dos header
|
||||
@param Hdr The buffer in which to return the PE32, PE32+, or TE header.
|
||||
|
||||
@retval EFI_SUCCESS Successfully get the machine type.
|
||||
@retval EFI_NOT_FOUND The file is not found.
|
||||
@retval EFI_LOAD_ERROR File is not a valid image file.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
BmGetImageHeader (
|
||||
IN EFI_HANDLE Device,
|
||||
IN CHAR16 *FileName,
|
||||
OUT EFI_IMAGE_DOS_HEADER *DosHeader,
|
||||
OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
|
||||
EFI_FILE_HANDLE Root;
|
||||
EFI_FILE_HANDLE ThisFile;
|
||||
UINTN BufferSize;
|
||||
UINT64 FileSize;
|
||||
EFI_FILE_INFO *Info;
|
||||
|
||||
Root = NULL;
|
||||
ThisFile = NULL;
|
||||
//
|
||||
// Handle the file system interface to the device
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
Device,
|
||||
&gEfiSimpleFileSystemProtocolGuid,
|
||||
(VOID *) &Volume
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Status = Volume->OpenVolume (
|
||||
Volume,
|
||||
&Root
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Root = NULL;
|
||||
goto Done;
|
||||
}
|
||||
ASSERT (Root != NULL);
|
||||
Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
ASSERT (ThisFile != NULL);
|
||||
|
||||
//
|
||||
// Get file size
|
||||
//
|
||||
BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
|
||||
do {
|
||||
Info = NULL;
|
||||
Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
Status = ThisFile->GetInfo (
|
||||
ThisFile,
|
||||
&gEfiFileInfoGuid,
|
||||
&BufferSize,
|
||||
Info
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||
FreePool (Info);
|
||||
goto Done;
|
||||
}
|
||||
FreePool (Info);
|
||||
} while (TRUE);
|
||||
|
||||
FileSize = Info->FileSize;
|
||||
FreePool (Info);
|
||||
|
||||
//
|
||||
// Read dos header
|
||||
//
|
||||
BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);
|
||||
Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader);
|
||||
if (EFI_ERROR (Status) ||
|
||||
BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) ||
|
||||
FileSize <= DosHeader->e_lfanew ||
|
||||
DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
|
||||
Status = EFI_LOAD_ERROR;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Move to PE signature
|
||||
//
|
||||
Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_LOAD_ERROR;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Read and check PE signature
|
||||
//
|
||||
BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
|
||||
Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32);
|
||||
if (EFI_ERROR (Status) ||
|
||||
BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) ||
|
||||
Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
|
||||
Status = EFI_LOAD_ERROR;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Check PE32 or PE32+ magic
|
||||
//
|
||||
if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
|
||||
Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
||||
Status = EFI_LOAD_ERROR;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Done:
|
||||
if (ThisFile != NULL) {
|
||||
ThisFile->Close (ThisFile);
|
||||
}
|
||||
if (Root != NULL) {
|
||||
Root->Close (Root);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This routine adjust the memory information for different memory type and
|
||||
save them into the variables for next boot.
|
||||
|
@ -505,3 +365,22 @@ BmSetVariableAndReportStatusCodeOnError (
|
|||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Print the device path info.
|
||||
|
||||
@param DevicePath The device path need to print.
|
||||
**/
|
||||
VOID
|
||||
BmPrintDp (
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||
)
|
||||
{
|
||||
CHAR16 *Str;
|
||||
|
||||
Str = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
|
||||
DEBUG ((EFI_D_INFO, "%s", Str));
|
||||
if (Str != NULL) {
|
||||
FreePool (Str);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,6 +100,37 @@ CHAR16 *
|
|||
IN EFI_HANDLE Handle
|
||||
);
|
||||
|
||||
#define BM_OPTION_NAME_LEN sizeof ("SysPrep####")
|
||||
extern CHAR16 *mBmLoadOptionName[];
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(*VARIABLE_VISITOR) (
|
||||
CHAR16 *Name,
|
||||
EFI_GUID *Guid,
|
||||
VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Call Visitor function for each variable in variable storage.
|
||||
|
||||
@param Visitor Visitor function.
|
||||
@param Context The context passed to Visitor function.
|
||||
**/
|
||||
VOID
|
||||
ForEachVariable (
|
||||
VARIABLE_VISITOR Visitor,
|
||||
VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Repair all the controllers according to the Driver Health status queried.
|
||||
**/
|
||||
VOID
|
||||
BmRepairAllControllers (
|
||||
VOID
|
||||
);
|
||||
|
||||
#define BM_HOTKEY_SIGNATURE SIGNATURE_32 ('b', 'm', 'h', 'k')
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
|
@ -139,7 +170,7 @@ BmLoadEfiBootOption (
|
|||
/**
|
||||
Get the Option Number that wasn't used.
|
||||
|
||||
@param OrderVariableName Could be L"BootOrder" or L"DriverOrder".
|
||||
@param LoadOptionType Load option type.
|
||||
@param FreeOptionNumber To receive the minimal free option number.
|
||||
|
||||
@retval EFI_SUCCESS The option number is found
|
||||
|
@ -149,8 +180,8 @@ BmLoadEfiBootOption (
|
|||
**/
|
||||
EFI_STATUS
|
||||
BmGetFreeOptionNumber (
|
||||
IN CHAR16 *OrderVariableName,
|
||||
OUT UINT16 *FreeOptionNumber
|
||||
IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType,
|
||||
OUT UINT16 *FreeOptionNumber
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -294,6 +325,42 @@ BmSetVariableAndReportStatusCodeOnError (
|
|||
IN VOID *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Get the load option by its device path.
|
||||
|
||||
@param FilePath The device path pointing to a load option.
|
||||
It could be a short-form device path.
|
||||
@param FullPath Return the full device path of the load option after
|
||||
short-form device path expanding.
|
||||
Caller is responsible to free it.
|
||||
@param FileSize Return the load option size.
|
||||
|
||||
@return The load option buffer. Caller is responsible to free the memory.
|
||||
**/
|
||||
VOID *
|
||||
BmGetLoadOptionBuffer (
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
|
||||
OUT UINTN *FileSize
|
||||
);
|
||||
|
||||
/**
|
||||
Return whether the PE header of the load option is valid or not.
|
||||
|
||||
@param[in] Type The load option type.
|
||||
@param[in] FileBuffer The PE file buffer of the load option.
|
||||
@param[in] FileSize The size of the load option file.
|
||||
|
||||
@retval TRUE The PE header of the load option is valid.
|
||||
@retval FALSE The PE header of the load option is not valid.
|
||||
**/
|
||||
BOOLEAN
|
||||
BmIsLoadOptionPeHeaderValid (
|
||||
IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE Type,
|
||||
IN VOID *FileBuffer,
|
||||
IN UINTN FileSize
|
||||
);
|
||||
|
||||
/**
|
||||
Function compares a device path data structure to that of all the nodes of a
|
||||
second device path instance.
|
||||
|
@ -361,4 +428,14 @@ BmRepairAllControllers (
|
|||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Print the device path info.
|
||||
|
||||
@param DevicePath The device path need to print.
|
||||
**/
|
||||
VOID
|
||||
BmPrintDp (
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||
);
|
||||
|
||||
#endif // _INTERNAL_BM_H_
|
||||
|
|
|
@ -47,6 +47,12 @@ CHAR16 *mReadOnlyVariables[] = {
|
|||
EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME
|
||||
};
|
||||
|
||||
CHAR16 *mBdsLoadOptionName[] = {
|
||||
L"Driver",
|
||||
L"SysPrep",
|
||||
L"Boot"
|
||||
};
|
||||
|
||||
CHAR16 mRecoveryBoot[] = L"Recovery Boot";
|
||||
/**
|
||||
Event to Connect ConIn.
|
||||
|
@ -75,7 +81,7 @@ BdsDxeOnConnectConInCallBack (
|
|||
// Should not enter this case, if enter, the keyboard will not work.
|
||||
// May need platfrom policy to connect keyboard.
|
||||
//
|
||||
DEBUG ((EFI_D_WARN, "[Bds] ASSERT Connect ConIn failed!!!\n"));
|
||||
DEBUG ((EFI_D_WARN, "[Bds] Connect ConIn failed - %r!!!\n", Status));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -553,103 +559,55 @@ DefaultBootBehavior (
|
|||
}
|
||||
|
||||
/**
|
||||
The function will go through the driver option link list, load and start
|
||||
every driver the driver option device path point to.
|
||||
The function will load and start every Driver####/SysPrep####.
|
||||
|
||||
@param DriverOption Input driver option array.
|
||||
@param DriverOptionCount Input driver option count.
|
||||
@param LoadOptions Load option array.
|
||||
@param LoadOptionCount Load option count.
|
||||
|
||||
**/
|
||||
VOID
|
||||
LoadDrivers (
|
||||
IN EFI_BOOT_MANAGER_LOAD_OPTION *DriverOption,
|
||||
IN UINTN DriverOptionCount
|
||||
ProcessLoadOptions (
|
||||
IN EFI_BOOT_MANAGER_LOAD_OPTION *LoadOptions,
|
||||
IN UINTN LoadOptionCount
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
EFI_HANDLE ImageHandle;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
|
||||
BOOLEAN ReconnectAll;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
BOOLEAN ReconnectAll;
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;
|
||||
|
||||
ReconnectAll = FALSE;
|
||||
LoadOptionType = LoadOptionTypeMax;
|
||||
|
||||
//
|
||||
// Process the driver option
|
||||
//
|
||||
for (Index = 0; Index < DriverOptionCount; Index++) {
|
||||
for (Index = 0; Index < LoadOptionCount; Index++) {
|
||||
//
|
||||
// If a load option is not marked as LOAD_OPTION_ACTIVE,
|
||||
// the boot manager will not automatically load the option.
|
||||
// All the load options in the array should be of the same type.
|
||||
//
|
||||
if ((DriverOption[Index].Attributes & LOAD_OPTION_ACTIVE) == 0) {
|
||||
continue;
|
||||
if (LoadOptionType == LoadOptionTypeMax) {
|
||||
LoadOptionType = LoadOptions[Index].OptionType;
|
||||
}
|
||||
|
||||
//
|
||||
// If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
|
||||
// then all of the EFI drivers in the system will be disconnected and
|
||||
// reconnected after the last driver load option is processed.
|
||||
//
|
||||
if ((DriverOption[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0) {
|
||||
ASSERT (LoadOptionType == LoadOptions[Index].OptionType);
|
||||
ASSERT (LoadOptionType == LoadOptionTypeDriver || LoadOptionType == LoadOptionTypeSysPrep);
|
||||
|
||||
Status = EfiBootManagerProcessLoadOption (&LoadOptions[Index]);
|
||||
|
||||
if (!EFI_ERROR (Status) && ((LoadOptions[Index].Attributes & LOAD_OPTION_FORCE_RECONNECT) != 0)) {
|
||||
ReconnectAll = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure the driver path is connected.
|
||||
//
|
||||
EfiBootManagerConnectDevicePath (DriverOption[Index].FilePath, NULL);
|
||||
|
||||
//
|
||||
// Load and start the image that Driver#### describes
|
||||
//
|
||||
Status = gBS->LoadImage (
|
||||
FALSE,
|
||||
gImageHandle,
|
||||
DriverOption[Index].FilePath,
|
||||
NULL,
|
||||
0,
|
||||
&ImageHandle
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);
|
||||
|
||||
//
|
||||
// Verify whether this image is a driver, if not,
|
||||
// exit it and continue to parse next load option
|
||||
//
|
||||
if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {
|
||||
gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
ImageInfo->LoadOptionsSize = DriverOption[Index].OptionalDataSize;
|
||||
ImageInfo->LoadOptions = DriverOption[Index].OptionalData;
|
||||
//
|
||||
// Before calling the image, enable the Watchdog Timer for
|
||||
// the 5 Minute period
|
||||
//
|
||||
gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
|
||||
|
||||
DriverOption[Index].Status = gBS->StartImage (ImageHandle, &DriverOption[Index].ExitDataSize, &DriverOption[Index].ExitData);
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Driver Return Status = %r\n", DriverOption[Index].Status));
|
||||
|
||||
//
|
||||
// Clear the Watchdog Timer after the image returns
|
||||
//
|
||||
gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Process the LOAD_OPTION_FORCE_RECONNECT driver option
|
||||
// If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
|
||||
// then all of the EFI drivers in the system will be disconnected and
|
||||
// reconnected after the last driver load option is processed.
|
||||
//
|
||||
if (ReconnectAll) {
|
||||
if (ReconnectAll && LoadOptionType == LoadOptionTypeDriver) {
|
||||
EfiBootManagerDisconnectAll ();
|
||||
EfiBootManagerConnectAll ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -855,9 +813,8 @@ BdsEntry (
|
|||
IN EFI_BDS_ARCH_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION *DriverOption;
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
|
||||
UINTN DriverOptionCount;
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION *LoadOptions;
|
||||
UINTN LoadOptionCount;
|
||||
CHAR16 *FirmwareVendor;
|
||||
EFI_EVENT HotkeyTriggered;
|
||||
UINT64 OsIndication;
|
||||
|
@ -867,8 +824,11 @@ BdsEntry (
|
|||
UINT16 BootTimeOut;
|
||||
EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;
|
||||
UINTN Index;
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
|
||||
UINT16 *BootNext;
|
||||
CHAR16 BootNextVariableName[sizeof ("Boot####")];
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;
|
||||
BOOLEAN BootFwUi;
|
||||
|
||||
HotkeyTriggered = NULL;
|
||||
Status = EFI_SUCCESS;
|
||||
|
@ -939,7 +899,7 @@ BdsEntry (
|
|||
// Initialize L"BootOptionSupport" EFI global variable.
|
||||
// Lazy-ConIn implictly disables BDS hotkey.
|
||||
//
|
||||
BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_APP;
|
||||
BootOptionSupport = EFI_BOOT_OPTION_SUPPORT_APP | EFI_BOOT_OPTION_SUPPORT_SYSPREP;
|
||||
if (!PcdGetBool (PcdConInConnectOnDemand)) {
|
||||
BootOptionSupport |= EFI_BOOT_OPTION_SUPPORT_KEY;
|
||||
SET_BOOT_OPTION_SUPPORT_KEY_COUNT (BootOptionSupport, 3);
|
||||
|
@ -1010,11 +970,11 @@ BdsEntry (
|
|||
EfiBootManagerStartHotkeyService (&HotkeyTriggered);
|
||||
|
||||
//
|
||||
// Load Driver Options
|
||||
// Execute Driver Options
|
||||
//
|
||||
DriverOption = EfiBootManagerGetLoadOptions (&DriverOptionCount, LoadOptionTypeDriver);
|
||||
LoadDrivers (DriverOption, DriverOptionCount);
|
||||
EfiBootManagerFreeLoadOptions (DriverOption, DriverOptionCount);
|
||||
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeDriver);
|
||||
ProcessLoadOptions (LoadOptions, LoadOptionCount);
|
||||
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
|
||||
|
||||
//
|
||||
// Connect consoles
|
||||
|
@ -1059,23 +1019,28 @@ BdsEntry (
|
|||
PERF_END (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);
|
||||
|
||||
DEBUG_CODE (
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
|
||||
UINTN BootOptionCount;
|
||||
UINTN Index;
|
||||
|
||||
BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
|
||||
DEBUG ((EFI_D_INFO, "[Bds]=============Dumping Boot Options=============\n"));
|
||||
for (Index = 0; Index < BootOptionCount; Index++) {
|
||||
UINTN Index;
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType;
|
||||
DEBUG ((EFI_D_INFO, "[Bds]=============Begin Load Options Dumping ...=============\n"));
|
||||
for (LoadOptionType = 0; LoadOptionType < LoadOptionTypeMax; LoadOptionType++) {
|
||||
DEBUG ((
|
||||
EFI_D_INFO, "[Bds]Boot%04x: %s \t\t 0x%04x\n",
|
||||
BootOptions[Index].OptionNumber,
|
||||
BootOptions[Index].Description,
|
||||
BootOptions[Index].Attributes
|
||||
EFI_D_INFO, " %s Options:\n",
|
||||
mBdsLoadOptionName[LoadOptionType]
|
||||
));
|
||||
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionType);
|
||||
for (Index = 0; Index < LoadOptionCount; Index++) {
|
||||
DEBUG ((
|
||||
EFI_D_INFO, " %s%04x: %s \t\t 0x%04x\n",
|
||||
mBdsLoadOptionName[LoadOptionType],
|
||||
LoadOptions[Index].OptionNumber,
|
||||
LoadOptions[Index].Description,
|
||||
LoadOptions[Index].Attributes
|
||||
));
|
||||
}
|
||||
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
|
||||
}
|
||||
DEBUG ((EFI_D_INFO, "[Bds]=============Dumping Boot Options Finished====\n"));
|
||||
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
|
||||
);
|
||||
DEBUG ((EFI_D_INFO, "[Bds]=============End Load Options Dumping=============\n"));
|
||||
);
|
||||
|
||||
//
|
||||
// Boot to Boot Manager Menu when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot
|
||||
|
@ -1088,10 +1053,15 @@ BdsEntry (
|
|||
&DataSize,
|
||||
&OsIndication
|
||||
);
|
||||
if (!EFI_ERROR(Status) && ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0)) {
|
||||
//
|
||||
// Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
OsIndication = 0;
|
||||
}
|
||||
|
||||
BootFwUi = (BOOLEAN) ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0);
|
||||
//
|
||||
// Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS
|
||||
//
|
||||
if (BootFwUi) {
|
||||
OsIndication &= ~((UINT64) EFI_OS_INDICATIONS_BOOT_TO_FW_UI);
|
||||
Status = gRT->SetVariable (
|
||||
L"OsIndications",
|
||||
|
@ -1104,7 +1074,12 @@ BdsEntry (
|
|||
// Changing the content without increasing its size with current variable implementation shouldn't fail.
|
||||
//
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
//
|
||||
// Launch Boot Manager Menu directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot
|
||||
//
|
||||
if (BootFwUi) {
|
||||
//
|
||||
// Follow generic rule, Call BdsDxeOnConnectConInCallBack to connect ConIn before enter UI
|
||||
//
|
||||
|
@ -1113,24 +1088,35 @@ BdsEntry (
|
|||
}
|
||||
|
||||
//
|
||||
// Directly boot to Boot Manager Menu.
|
||||
// Directly enter the setup page.
|
||||
// BootManagerMenu always contains the correct information even call fails.
|
||||
//
|
||||
EfiBootManagerGetBootManagerMenu (&BootOption);
|
||||
EfiBootManagerBoot (&BootOption);
|
||||
EfiBootManagerFreeLoadOption (&BootOption);
|
||||
} else {
|
||||
PERF_START (NULL, "BdsWait", "BDS", 0);
|
||||
BdsWait (HotkeyTriggered);
|
||||
PERF_END (NULL, "BdsWait", "BDS", 0);
|
||||
|
||||
//
|
||||
// BdsReadKeys() be removed after all keyboard drivers invoke callback in timer callback.
|
||||
//
|
||||
BdsReadKeys ();
|
||||
|
||||
EfiBootManagerHotkeyBoot ();
|
||||
EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
|
||||
EfiBootManagerBoot (&BootManagerMenu);
|
||||
EfiBootManagerFreeLoadOption (&BootManagerMenu);
|
||||
}
|
||||
|
||||
//
|
||||
// Execute SysPrep####
|
||||
//
|
||||
LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypeSysPrep);
|
||||
ProcessLoadOptions (LoadOptions, LoadOptionCount);
|
||||
EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
|
||||
|
||||
//
|
||||
// Execute Key####
|
||||
//
|
||||
PERF_START (NULL, "BdsWait", "BDS", 0);
|
||||
BdsWait (HotkeyTriggered);
|
||||
PERF_END (NULL, "BdsWait", "BDS", 0);
|
||||
|
||||
//
|
||||
// BdsReadKeys() be removed after all keyboard drivers invoke callback in timer callback.
|
||||
//
|
||||
BdsReadKeys ();
|
||||
|
||||
EfiBootManagerHotkeyBoot ();
|
||||
|
||||
//
|
||||
// Boot to "BootNext"
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue