/** @file\r
Library functions which relates with booting.\r
\r
-Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
return FileBuffer;\r
}\r
\r
+ Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
//\r
- // For device boot option only pointing to the removable device handle, \r
- // should make sure all its children handles (its child partion or media handles) are created and connected. \r
+ // For device boot option only pointing to the removable device handle,\r
+ // should make sure all its children handles (its child partion or media handles)\r
+ // are created and connected.\r
//\r
gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
\r
// returned. After the Block IO protocol is reinstalled, subsequent\r
// Block IO read/write will success.\r
//\r
- Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);\r
- ASSERT_EFI_ERROR (Status);\r
Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);\r
ASSERT_EFI_ERROR (Status);\r
Buffer = AllocatePool (BlockIo->Media->BlockSize);\r
return BmGetFileBufferFromLoadFiles (FilePath, FullPath, FileSize);\r
}\r
\r
+/**\r
+ Check if it's a Device Path pointing to BootManagerMenu.\r
+\r
+ @param DevicePath Input device path.\r
+\r
+ @retval TRUE The device path is BootManagerMenu File Device Path.\r
+ @retval FALSE The device path is NOT BootManagerMenu File Device Path.\r
+**/\r
+BOOLEAN\r
+BmIsBootManagerMenuFilePath (\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+)\r
+{\r
+ EFI_HANDLE FvHandle;\r
+ VOID *NameGuid;\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePath, &FvHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePath);\r
+ if (NameGuid != NULL) {\r
+ return CompareGuid (NameGuid, PcdGetPtr (PcdBootManagerMenuFile));\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
/**\r
Attempt to boot the EFI boot option. This routine sets L"BootCurent" and\r
also signals the EFI ready to boot event. If the device path for the option\r
UINTN OptionNumber;\r
UINTN OriginalOptionNumber;\r
EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
- EFI_DEVICE_PATH_PROTOCOL *Node;\r
EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath;\r
- EFI_HANDLE FvHandle;\r
VOID *FileBuffer;\r
UINTN FileSize;\r
EFI_BOOT_LOGO_PROTOCOL *BootLogo;\r
EFI_EVENT LegacyBootEvent;\r
- UINTN RamDiskSizeInPages;\r
\r
if (BootOption == NULL) {\r
return;\r
// 3. Signal the EVT_SIGNAL_READY_TO_BOOT event when we are about to load and execute\r
// the boot option.\r
//\r
- Node = BootOption->FilePath;\r
- Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &Node, &FvHandle);\r
- if (!EFI_ERROR (Status) && CompareGuid (\r
- EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) Node),\r
- PcdGetPtr (PcdBootManagerMenuFile)\r
- )) {\r
+ if (BmIsBootManagerMenuFilePath (BootOption->FilePath)) {\r
DEBUG ((EFI_D_INFO, "[Bds] Booting Boot Manager Menu.\n"));\r
BmStopHotkeyService (NULL, NULL);\r
} else {\r
PERF_START_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumber);\r
\r
//\r
- // 5. Load EFI boot option to ImageHandle\r
+ // 5. Adjust the different type memory page number just before booting\r
+ // and save the updated info into the variable for next boot to use\r
+ //\r
+ BmSetMemoryTypeInformationVariable (\r
+ (BOOLEAN) ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_BOOT)\r
+ );\r
+\r
+ //\r
+ // 6. Load EFI boot option to ImageHandle\r
//\r
+ DEBUG_CODE_BEGIN ();\r
+ if (BootOption->Description == NULL) {\r
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD, "[Bds]Booting from unknown device path\n"));\r
+ } else {\r
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD, "[Bds]Booting %s\n", BootOption->Description));\r
+ }\r
+ DEBUG_CODE_END ();\r
+\r
ImageHandle = NULL;\r
RamDiskDevicePath = NULL;\r
if (DevicePathType (BootOption->FilePath) != BBS_DEVICE_PATH) {\r
}\r
}\r
\r
- //\r
- // 6. Adjust the different type memory page number just before booting\r
- // and save the updated info into the variable for next boot to use\r
- //\r
- if (RamDiskDevicePath == NULL) {\r
- RamDiskSizeInPages = 0;\r
- } else {\r
- BmGetRamDiskMemoryInfo (RamDiskDevicePath, &RamDiskSizeInPages);\r
- }\r
- BmSetMemoryTypeInformationVariable (\r
- (BOOLEAN) ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_BOOT),\r
- RamDiskSizeInPages\r
- );\r
-\r
- DEBUG_CODE_BEGIN();\r
- if (BootOption->Description == NULL) {\r
- DEBUG ((DEBUG_INFO | DEBUG_LOAD, "[Bds]Booting from unknown device path\n"));\r
- } else {\r
- DEBUG ((DEBUG_INFO | DEBUG_LOAD, "[Bds]Booting %s\n", BootOption->Description));\r
- }\r
- DEBUG_CODE_END();\r
-\r
//\r
// Check to see if we should legacy BOOT. If yes then do the legacy boot\r
// Write boot to OS performance data for Legacy boot\r
}\r
\r
//\r
- // Parse load file, assuming UEFI Network boot option\r
+ // Parse load file protocol\r
//\r
gBS->LocateHandleBuffer (\r
ByProtocol,\r
&Handles\r
);\r
for (Index = 0; Index < HandleCount; Index++) {\r
+ //\r
+ // Ignore BootManagerMenu. its boot option will be created by EfiBootManagerGetBootManagerMenu().\r
+ //\r
+ if (BmIsBootManagerMenuFilePath (DevicePathFromHandle (Handles[Index]))) {\r
+ continue;\r
+ }\r
\r
Description = BmGetBootDescription (Handles[Index]);\r
BootOptions = ReallocatePool (\r
// Only check those added by BDS\r
// so that the boot options added by end-user or OS installer won't be deleted\r
//\r
- if (EfiBootManagerFindLoadOption (&NvBootOptions[Index], BootOptions, BootOptionCount) == (UINTN) -1) {\r
+ if (EfiBootManagerFindLoadOption (&NvBootOptions[Index], BootOptions, BootOptionCount) == -1) {\r
Status = EfiBootManagerDeleteLoadOptionVariable (NvBootOptions[Index].OptionNumber, LoadOptionTypeBoot);\r
//\r
// Deleting variable with current variable implementation shouldn't fail.\r
// Add new EFI boot options to NV\r
//\r
for (Index = 0; Index < BootOptionCount; Index++) {\r
- if (EfiBootManagerFindLoadOption (&BootOptions[Index], NvBootOptions, NvBootOptionCount) == (UINTN) -1) {\r
+ if (EfiBootManagerFindLoadOption (&BootOptions[Index], NvBootOptions, NvBootOptionCount) == -1) {\r
EfiBootManagerAddLoadOptionVariable (&BootOptions[Index], (UINTN) -1);\r
//\r
// Try best to add the boot options so continue upon failure.\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
+ UINTN HandleCount;\r
+ EFI_HANDLE *Handles;\r
+ UINTN Index;\r
VOID *Data;\r
UINTN DataSize;\r
\r
- Data = NULL;\r
- Status = GetSectionFromFv (\r
- PcdGetPtr (PcdBootManagerMenuFile),\r
- EFI_SECTION_PE32,\r
- 0,\r
- (VOID **) &Data,\r
- &DataSize\r
- );\r
- if (Data != NULL) {\r
- FreePool (Data);\r
- }\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_WARN, "[Bds]BootManagerMenu FFS section can not be found, skip its boot option registration\n"));\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
+ DevicePath = NULL;\r
+ Description = NULL;\r
//\r
- // Get BootManagerMenu application's description from EFI User Interface Section.\r
+ // Try to find BootManagerMenu from LoadFile protocol\r
//\r
- Status = GetSectionFromFv (\r
- PcdGetPtr (PcdBootManagerMenuFile),\r
- EFI_SECTION_USER_INTERFACE,\r
- 0,\r
- (VOID **) &Description,\r
- &DescriptionLength\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Description = NULL;\r
+ gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiLoadFileProtocolGuid,\r
+ NULL,\r
+ &HandleCount,\r
+ &Handles\r
+ );\r
+ for (Index = 0; Index < HandleCount; Index++) {\r
+ if (BmIsBootManagerMenuFilePath (DevicePathFromHandle (Handles[Index]))) {\r
+ DevicePath = DuplicateDevicePath (DevicePathFromHandle (Handles[Index]));\r
+ Description = BmGetBootDescription (Handles[Index]);\r
+ break;\r
+ }\r
+ }\r
+ if (HandleCount != 0) {\r
+ FreePool (Handles);\r
}\r
\r
- EfiInitializeFwVolDevicepathNode (&FileNode, PcdGetPtr (PcdBootManagerMenuFile));\r
- Status = gBS->HandleProtocol (\r
- gImageHandle,\r
- &gEfiLoadedImageProtocolGuid,\r
- (VOID **) &LoadedImage\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- DevicePath = AppendDevicePathNode (\r
- DevicePathFromHandle (LoadedImage->DeviceHandle),\r
- (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
- );\r
- ASSERT (DevicePath != NULL);\r
+ if (DevicePath == NULL) {\r
+ Data = NULL;\r
+ Status = GetSectionFromFv (\r
+ PcdGetPtr (PcdBootManagerMenuFile),\r
+ EFI_SECTION_PE32,\r
+ 0,\r
+ (VOID **) &Data,\r
+ &DataSize\r
+ );\r
+ if (Data != NULL) {\r
+ FreePool (Data);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_WARN, "[Bds]BootManagerMenu FFS section can not be found, skip its boot option registration\n"));\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Get BootManagerMenu application's description from EFI User Interface Section.\r
+ //\r
+ Status = GetSectionFromFv (\r
+ PcdGetPtr (PcdBootManagerMenuFile),\r
+ EFI_SECTION_USER_INTERFACE,\r
+ 0,\r
+ (VOID **) &Description,\r
+ &DescriptionLength\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Description = NULL;\r
+ }\r
+\r
+ EfiInitializeFwVolDevicepathNode (&FileNode, PcdGetPtr (PcdBootManagerMenuFile));\r
+ Status = gBS->HandleProtocol (\r
+ gImageHandle,\r
+ &gEfiLoadedImageProtocolGuid,\r
+ (VOID **) &LoadedImage\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ DevicePath = AppendDevicePathNode (\r
+ DevicePathFromHandle (LoadedImage->DeviceHandle),\r
+ (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
+ );\r
+ ASSERT (DevicePath != NULL);\r
+ }\r
\r
Status = EfiBootManagerInitializeLoadOption (\r
BootOption,\r
UINTN BootOptionCount;\r
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
UINTN Index;\r
- EFI_DEVICE_PATH_PROTOCOL *Node;\r
- EFI_HANDLE FvHandle;\r
\r
BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
\r
for (Index = 0; Index < BootOptionCount; Index++) {\r
- Node = BootOptions[Index].FilePath;\r
- Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &Node, &FvHandle);\r
- if (!EFI_ERROR (Status)) {\r
- if (CompareGuid (\r
- EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) Node),\r
- PcdGetPtr (PcdBootManagerMenuFile)\r
- )\r
- ) { \r
+ if (BmIsBootManagerMenuFilePath (BootOptions[Index].FilePath)) {\r
Status = EfiBootManagerInitializeLoadOption (\r
BootOption,\r
BootOptions[Index].OptionNumber,\r
);\r
ASSERT_EFI_ERROR (Status);\r
break;\r
- }\r
}\r
}\r
\r