mirror of https://github.com/acidanthera/audk.git
Merge EDK tracker 892 to EDK II.
892 Internal Shell sometimes can't boot when boot option is not enumerated git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4112 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
26096d369d
commit
76bb6efe95
|
@ -122,6 +122,7 @@ Returns:
|
|||
EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
|
||||
EFI_BLOCK_IO_PROTOCOL *BlkIo;
|
||||
VOID *Buffer;
|
||||
LIST_ENTRY TempBootLists;
|
||||
|
||||
//
|
||||
// Record the performance data for End of BDS
|
||||
|
@ -178,6 +179,23 @@ Returns:
|
|||
//
|
||||
return BdsLibDoLegacyBoot (Option);
|
||||
}
|
||||
|
||||
//
|
||||
// If the boot option point to Internal FV shell, make sure it is valid
|
||||
//
|
||||
Status = UpdateFvFileDevicePath (&DevicePath, &gEfiShellFileGuid);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
if (Option->DevicePath != NULL) {
|
||||
FreePool (Option->DevicePath);
|
||||
}
|
||||
Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath));
|
||||
CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));
|
||||
//
|
||||
// Update the shell boot option
|
||||
//
|
||||
InitializeListHead (&TempBootLists);
|
||||
BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder");
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Booting EFI 1.1 way %S\n", Option->Description));
|
||||
|
||||
|
@ -1090,3 +1108,203 @@ Returns:
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UpdateFvFileDevicePath (
|
||||
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
|
||||
IN EFI_GUID *FileGuid
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
According to a file guild, check a Fv file device path is valid. If it is invalid,
|
||||
try to return the valid device path.
|
||||
FV address maybe changes for memory layout adjust from time to time, use this funciton
|
||||
could promise the Fv file device path is right.
|
||||
|
||||
Arguments:
|
||||
DevicePath - on input, the Fv file device path need to check
|
||||
on output, the updated valid Fv file device path
|
||||
|
||||
FileGuid - the Fv file guild
|
||||
|
||||
Returns:
|
||||
EFI_INVALID_PARAMETER - the input DevicePath or FileGuid is invalid parameter
|
||||
EFI_UNSUPPORTED - the input DevicePath does not contain Fv file guild at all
|
||||
EFI_ALREADY_STARTED - the input DevicePath has pointed to Fv file, it is valid
|
||||
EFI_SUCCESS - has successfully updated the invalid DevicePath, and return the updated
|
||||
device path in DevicePath
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
|
||||
EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;
|
||||
EFI_STATUS Status;
|
||||
EFI_GUID *GuidPoint;
|
||||
UINTN Index;
|
||||
UINTN FvHandleCount;
|
||||
EFI_HANDLE *FvHandleBuffer;
|
||||
EFI_FV_FILETYPE Type;
|
||||
UINTN Size;
|
||||
EFI_FV_FILE_ATTRIBUTES Attributes;
|
||||
UINT32 AuthenticationStatus;
|
||||
BOOLEAN FindFvFile;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
|
||||
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode;
|
||||
EFI_HANDLE FoundFvHandle;
|
||||
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
|
||||
|
||||
if ((DevicePath == NULL) || (*DevicePath == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (FileGuid == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
//
|
||||
// Check whether the device path point to the default the input Fv file
|
||||
//
|
||||
TempDevicePath = *DevicePath;
|
||||
LastDeviceNode = TempDevicePath;
|
||||
while (!EfiIsDevicePathEnd (TempDevicePath)) {
|
||||
LastDeviceNode = TempDevicePath;
|
||||
TempDevicePath = EfiNextDevicePathNode (TempDevicePath);
|
||||
}
|
||||
|
||||
GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LastDeviceNode);
|
||||
|
||||
if (GuidPoint == NULL) {
|
||||
//
|
||||
// if this option does not points to a Fv file, just return EFI_UNSUPPORTED
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (!CompareGuid (GuidPoint, FileGuid)) {
|
||||
//
|
||||
// If the Fv file is not the input file guid, just return EFI_UNSUPPORTED
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether the input Fv file device path is valid
|
||||
//
|
||||
TempDevicePath = *DevicePath;
|
||||
FoundFvHandle = NULL;
|
||||
Status = gBS->LocateDevicePath (
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
&TempDevicePath,
|
||||
&FoundFvHandle
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = gBS->HandleProtocol (
|
||||
FoundFvHandle,
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
(VOID **) &Fv
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Set FV ReadFile Buffer as NULL, only need to check whether input Fv file exist there
|
||||
//
|
||||
Status = Fv->ReadFile (
|
||||
Fv,
|
||||
FileGuid,
|
||||
NULL,
|
||||
&Size,
|
||||
&Type,
|
||||
&Attributes,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Look for the input wanted FV file in current FV
|
||||
// First, try to look for in Bds own FV. Bds and input wanted FV file usually are in the same FV
|
||||
//
|
||||
FindFvFile = FALSE;
|
||||
FoundFvHandle = NULL;
|
||||
Status = gBS->HandleProtocol (
|
||||
mBdsImageHandle,
|
||||
&gEfiLoadedImageProtocolGuid,
|
||||
&LoadedImage
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = gBS->HandleProtocol (
|
||||
LoadedImage->DeviceHandle,
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
(VOID **) &Fv
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = Fv->ReadFile (
|
||||
Fv,
|
||||
FileGuid,
|
||||
NULL,
|
||||
&Size,
|
||||
&Type,
|
||||
&Attributes,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
FindFvFile = TRUE;
|
||||
FoundFvHandle = LoadedImage->DeviceHandle;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Second, if fail to find, try to enumerate all FV
|
||||
//
|
||||
if (!FindFvFile) {
|
||||
gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
NULL,
|
||||
&FvHandleCount,
|
||||
&FvHandleBuffer
|
||||
);
|
||||
for (Index = 0; Index < FvHandleCount; Index++) {
|
||||
gBS->HandleProtocol (
|
||||
FvHandleBuffer[Index],
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
(VOID **) &Fv
|
||||
);
|
||||
|
||||
Status = Fv->ReadFile (
|
||||
Fv,
|
||||
FileGuid,
|
||||
NULL,
|
||||
&Size,
|
||||
&Type,
|
||||
&Attributes,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Skip if input Fv file not in the FV
|
||||
//
|
||||
continue;
|
||||
}
|
||||
FindFvFile = TRUE;
|
||||
FoundFvHandle = FvHandleBuffer[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FindFvFile) {
|
||||
//
|
||||
// Build the shell device path
|
||||
//
|
||||
NewDevicePath = DevicePathFromHandle (FoundFvHandle);
|
||||
EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid);
|
||||
NewDevicePath = AppendDevicePathNode (NewDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode);
|
||||
*DevicePath = NewDevicePath;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
|
|
@ -86,5 +86,11 @@ ClearDebugRegisters (
|
|||
VOID
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UpdateFvFileDevicePath (
|
||||
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
|
||||
IN EFI_GUID *FileGuid
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue