On 18 January 2018 at 15:01, Ming Huang heyi.guo@linaro.org wrote:
OsBootLib can create OS option after upgrade firmware.
Can you add a bit more explanation why you need this?
Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ming Huang huangming23@huawei.com Signed-off-by: Heyi Guo heyi.guo@linaro.org
Platform/Hisilicon/D03/D03.dsc | 1 + Platform/Hisilicon/D05/D05.dsc | 1 + Silicon/Hisilicon/Include/Library/OsBootLib.h | 47 ++ Silicon/Hisilicon/Library/OsBootLib/OsBoot.h | 124 +++++ Silicon/Hisilicon/Library/OsBootLib/OsBootLib.c | 217 +++++++++ Silicon/Hisilicon/Library/OsBootLib/OsBootLib.inf | 59 +++ Silicon/Hisilicon/Library/OsBootLib/OsBootLibMisc.c | 514 ++++++++++++++++++++ Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.c | 6 + Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf | 1 + 9 files changed, 970 insertions(+)
diff --git a/Platform/Hisilicon/D03/D03.dsc b/Platform/Hisilicon/D03/D03.dsc index 88c08dd..6f1164e 100644 --- a/Platform/Hisilicon/D03/D03.dsc +++ b/Platform/Hisilicon/D03/D03.dsc @@ -47,6 +47,7 @@ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
- OsBootLib|Silicon/Hisilicon/Library/OsBootLib/OsBootLib.inf
diff --git a/Platform/Hisilicon/D05/D05.dsc b/Platform/Hisilicon/D05/D05.dsc index 79890ef..52ffad5 100644 --- a/Platform/Hisilicon/D05/D05.dsc +++ b/Platform/Hisilicon/D05/D05.dsc @@ -55,6 +55,7 @@ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
- OsBootLib|Silicon/Hisilicon/Library/OsBootLib/OsBootLib.inf
!if $(NETWORK_IP6_ENABLE) == TRUE TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf diff --git a/Silicon/Hisilicon/Include/Library/OsBootLib.h b/Silicon/Hisilicon/Include/Library/OsBootLib.h new file mode 100644 index 0000000..f5cbc4a --- /dev/null +++ b/Silicon/Hisilicon/Include/Library/OsBootLib.h @@ -0,0 +1,47 @@ +/** @file +* +* Copyright (c) 2017, Hisilicon Limited. All rights reserved. +* Copyright (c) 2017, Linaro Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/
+#ifndef _OS_BOOT_LIB_H_ +#define _OS_BOOT_LIB_H_
+/**
- Remove invalid OS boot options, and then add new ones.
+*/ +EFI_STATUS +AdjustOsBootOrder (
- VOID
- );
+/**
- Try to find UEFI OSs and create the boot options which haven't been listed in BootOrder.
+*/ +EFI_STATUS +CreateOsBootOptions (
- VOID
- );
+/**
- Remove UEFI OS boot options when it is disappeared in system.
+*/ +EFI_STATUS +RemoveInvalidOsBootOptions (
- VOID
- );
+#endif diff --git a/Silicon/Hisilicon/Library/OsBootLib/OsBoot.h b/Silicon/Hisilicon/Library/OsBootLib/OsBoot.h new file mode 100644 index 0000000..1991471 --- /dev/null +++ b/Silicon/Hisilicon/Library/OsBootLib/OsBoot.h @@ -0,0 +1,124 @@ +/** @file +* +* Copyright (c) 2017, Hisilicon Limited. All rights reserved. +* Copyright (c) 2017, Linaro Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/
+#ifndef _OS_BOOT_H_ +#define _OS_BOOT_H_
+#include <PiDxe.h> +#include <PlatformArch.h> +#include <Uefi.h> +#include <Guid/FileInfo.h> +#include <Guid/GlobalVariable.h> +#include <IndustryStandard/PeImage.h> +#include <Library/BaseMemoryLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/DevicePathLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/OsBootLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/UefiBootManagerLib.h>
+#include <Protocol/BlockIo.h> +#include <Protocol/DevicePath.h> +#include <Protocol/DevicePathFromText.h> +#include <Protocol/DevicePathToText.h> +#include <Protocol/FirmwareVolume2.h> +#include <Protocol/SimpleFileSystem.h>
+typedef struct {
- CHAR16 *FilePathString;
- CHAR16 *Description;
- }UEFI_OS_BOOT_FILE;
+/**
- Check same boot option by device path.
+*/ +BOOLEAN +BeHaveSameBootOptionByDP (
- EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- CHAR16 *FileName
- );
+/**
- Remove UEFI OS boot options when it is disappeared in system.
+*/ +EFI_STATUS +RemoveInvalidOsBootOptions (
- VOID
- );
+/**
- Check Os Boot Option if exist in current system.
+*/ +BOOLEAN +BeInvalidOsBootOption (
- EFI_DEVICE_PATH_PROTOCOL *OptionDp
- );
+/**
- 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 +EFIAPI +OsBootGetImageHeader (
- IN EFI_HANDLE Device,
- IN CHAR16 *FileName,
- OUT EFI_IMAGE_DOS_HEADER *DosHeader,
- OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
- );
+UINTN +GetOptionPositionWithoutGpt (
- VOID
- );
+VOID +PrintDevicePath (
- CHAR16 *PreStr,
- EFI_DEVICE_PATH_PROTOCOL *Path
- );
+VOID +RemoveSuperfluousOption (
- EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions,
- UINT16 *OptionFlags,
- UINTN BootOptionCount
- );
+BOOLEAN +IsOptionAddedByOsBootLib (
- UINT16 *OptionDescription
- );
+#endif diff --git a/Silicon/Hisilicon/Library/OsBootLib/OsBootLib.c b/Silicon/Hisilicon/Library/OsBootLib/OsBootLib.c new file mode 100644 index 0000000..29b6b62 --- /dev/null +++ b/Silicon/Hisilicon/Library/OsBootLib/OsBootLib.c @@ -0,0 +1,217 @@ +/** @file +* +* Copyright (c) 2017, Hisilicon Limited. All rights reserved. +* Copyright (c) 2017, Linaro Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/
+#include "OsBoot.h"
+UEFI_OS_BOOT_FILE mUefiOsBootFiles[] = {
- {EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64, L"Uefi Default Boot"},
- {L"\BOOT\EFI\EFI\CENTOS\grubaa64.efi", L"Uefi CENTOS Boot"},
- {L"\EFI\centos\grubaa64.efi", L"Uefi CentOS Grub Boot"},
- {L"\EFI\debian\grubaa64.efi", L"Uefi Debian Grub Boot"},
- {L"\EFI\GRUB2\GRUBAA64.EFI", L"Hisilicon Linux Boot"},
- {L"\EFI\Microsoft\Boot\bootmgfw.efi", L"Uefi Windows Boot"},
- {L"\EFI\redhat\grub.efi", L"Uefi Redhat Boot"},
- {L"\EFI\SuSE\elilo.efi", L"Uefi SuSE Boot"},
- {L"\EFI\ubuntu\grubaa64.efi", L"Uefi Ubuntu Grub Boot"},
- {L"\EFI\ubuntu\shimx64.efi", L"Uefi Ubuntu Shimx64 Boot"},
- {L"\EFI\ubuntu\grubx64.efi", L"Uefi Ubuntu Grubx64 Boot"},
- {L"\EFI\ubuntu\shim.efi", L"Uefi Ubuntu Shim Boot"},
- {L"\EFI\ubuntu\grub.efi", L"Uefi Ubuntu Grub Boot"},
- {L"\EFI\fedora\shim.efi", L"Uefi Fedora Shim Boot"}
+};
+BOOLEAN +IsOptionAddedByOsBootLib (
- UINT16 *OptionDescription
- )
+{
- UINTN Index;
- for (Index = 0; Index < (sizeof (mUefiOsBootFiles) / sizeof (UEFI_OS_BOOT_FILE)); Index++) {
- if (StrCmp (mUefiOsBootFiles[Index].Description, OptionDescription) == 0) {
return TRUE;
- }
- }
- return FALSE;
+}
+/**
- Remove invalid OS boot options, and then add new ones.
+*/ +EFI_STATUS +AdjustOsBootOrder (
- VOID
- )
+{
- EFI_STATUS Status;
- Status = RemoveInvalidOsBootOptions ();
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = CreateOsBootOptions ();
- return Status;
+}
+/**
- Remove UEFI OS boot options when it is disappeared in system.
+*/ +EFI_STATUS +RemoveInvalidOsBootOptions (
- VOID
- )
+{
- EFI_STATUS Status;
- UINTN Index;
- UINT16 *OptionDelFlags;
- EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
- UINTN BootOptionCount;
- BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
- OptionDelFlags = AllocateZeroPool (BootOptionCount * sizeof(UINT16));
- if (OptionDelFlags == NULL) {
- goto exit;
- }
- for (Index = 0; Index < BootOptionCount; Index++) {
- if (OptionDelFlags[Index] == 0) {
if (BeInvalidOsBootOption (BootOptions[Index].FilePath)) {
Status = EfiBootManagerDeleteLoadOptionVariable (BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "DeleteLoadOptionVariable: %r\n", Status));
continue;
}
PrintDevicePath (L"Del Option,", BootOptions[Index].FilePath);
} else {
RemoveSuperfluousOption (&BootOptions[Index], OptionDelFlags, BootOptionCount - Index);
}
- }
- }
- exit:
- if (OptionDelFlags != NULL) {
- FreePool (OptionDelFlags);
- }
- EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
- return EFI_SUCCESS;
+}
+/**
- Try to find UEFI OSs and create the boot options which haven't been listed in BootOrder.
+*/ +EFI_STATUS +CreateOsBootOptions (
- VOID
- )
+{
- EFI_STATUS Status;
- EFI_HANDLE *FileSystemHandles;
- UINTN NumberFileSystemHandles;
- UINTN Index, Count;
- EFI_DEVICE_PATH_PROTOCOL *OsFileDP;
- EFI_BLOCK_IO_PROTOCOL *BlkIo;
- UINTN MaxFiles;
- EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
- EFI_IMAGE_DOS_HEADER DosHeader;
- EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
- //
- //Look for file system to find default Os boot load.
- //
- Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&NumberFileSystemHandles,
&FileSystemHandles
);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- MaxFiles = sizeof (mUefiOsBootFiles) / sizeof (UEFI_OS_BOOT_FILE);
- for (Index = 0; Index < NumberFileSystemHandles; Index++) {
- Status = gBS->HandleProtocol (
FileSystemHandles[Index],
&gEfiBlockIoProtocolGuid,
(VOID **) &BlkIo
);
- if (EFI_ERROR (Status)) {
continue;
- }
- Hdr.Union = &HdrData;
- for (Count = 0; Count < MaxFiles; Count++) {
//
//Read Boot File Path to check validation.
//
Status = OsBootGetImageHeader (
FileSystemHandles[Index],
mUefiOsBootFiles[Count].FilePathString,
&DosHeader,
Hdr
);
if (!EFI_ERROR (Status) &&
EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
OsFileDP = NULL;
OsFileDP = FileDevicePath (FileSystemHandles[Index], mUefiOsBootFiles[Count].FilePathString);
PrintDevicePath (L"Exist", OsFileDP);
if (!BeHaveSameBootOptionByDP (OsFileDP, mUefiOsBootFiles[Count].FilePathString)) {
//
// Create new BootOption if it is not present.
//
DEBUG ((DEBUG_INFO, "CreateOsBootOptions (), Make New Boot Option :%s.\n", mUefiOsBootFiles[Count].Description));
Status = EfiBootManagerInitializeLoadOption (
&NewOption,
LoadOptionNumberUnassigned,
LoadOptionTypeBoot,
LOAD_OPTION_ACTIVE,
mUefiOsBootFiles[Count].Description,
OsFileDP,
NULL,
0
);
ASSERT_EFI_ERROR (Status);
Status = EfiBootManagerAddLoadOptionVariable (&NewOption, GetOptionPositionWithoutGpt ());
ASSERT_EFI_ERROR (Status);
EfiBootManagerFreeLoadOption (&NewOption);
}
if(OsFileDP != NULL) {
FreePool (OsFileDP);
OsFileDP = NULL;
}
}
- }
- }
- if (NumberFileSystemHandles != 0) {
- FreePool (FileSystemHandles);
- }
- return EFI_SUCCESS;
+}
diff --git a/Silicon/Hisilicon/Library/OsBootLib/OsBootLib.inf b/Silicon/Hisilicon/Library/OsBootLib/OsBootLib.inf new file mode 100644 index 0000000..12e6d49 --- /dev/null +++ b/Silicon/Hisilicon/Library/OsBootLib/OsBootLib.inf @@ -0,0 +1,59 @@ +## @file +# Manager Os Boot option. +# Copyright (c) 2017, Hisilicon Limited. All rights reserved. +# Copyright (c) 2017, Linaro Limited. All rights reserved. +# +# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +##
+[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = OsBootLib
- FILE_GUID = e406c654-ccde-4d32-8362-0aec01725139
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = OsBootLib
+[Sources]
- OsBootLib.c
- OsBootLibMisc.c
+[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- Silicon/Hisilicon/HisiPkg.dec
+[LibraryClasses]
- BaseMemoryLib
- BaseLib
- DxeServicesLib
- DebugLib
- DxeServicesTableLib
- DevicePathLib
- MemoryAllocationLib
- PrintLib
- UefiRuntimeServicesTableLib
- UefiLib
- UefiBootServicesTableLib
- UefiBootManagerLib
+[Guids]
- gEfiGlobalVariableGuid
- gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## GUID
+[Protocols]
- gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
- gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES
- gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMES
- gEfiDevicePathProtocolGuid ## CONSUMES
- gEfiDevicePathToTextProtocolGuid
+[Pcd] diff --git a/Silicon/Hisilicon/Library/OsBootLib/OsBootLibMisc.c b/Silicon/Hisilicon/Library/OsBootLib/OsBootLibMisc.c new file mode 100644 index 0000000..4e6d895 --- /dev/null +++ b/Silicon/Hisilicon/Library/OsBootLib/OsBootLibMisc.c @@ -0,0 +1,514 @@ +/** @file +* +* Copyright (c) 2017, Hisilicon Limited. All rights reserved. +* Copyright (c) 2017, Linaro Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/
+#include "OsBoot.h"
+extern UEFI_OS_BOOT_FILE mUefiOsBootFiles[];
+/**
- Read file the headers of dos, image, optional header.
- @param Device SimpleFileSystem device handle
- @param FileSize File size
- @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 File.
- @retval EFI_LOAD_ERROR File is not a valid image file.
+**/ +EFI_STATUS +ReadDosHeader (
- EFI_FILE_HANDLE ThisFile,
- UINT64 FileSize,
- EFI_IMAGE_DOS_HEADER *DosHeader,
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION *Hdr
- )
+{
- EFI_STATUS Status;
- UINTN BufferSize;
- //
- // 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;
- DEBUG ((DEBUG_ERROR, "%a(%d):error!\n", __FUNCTION__,__LINE__));
- goto ErrReadDos;
- }
- //
- // Move to PE signature
- //
- Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew);
- if (EFI_ERROR (Status)) {
- Status = EFI_LOAD_ERROR;
- DEBUG((DEBUG_ERROR, "%a(%d):error!\n", __FUNCTION__,__LINE__));
- goto ErrReadDos;
- }
- //
- // Read and check PE signature
- //
- BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
- Status = ThisFile->Read (ThisFile, &BufferSize, (VOID*)(Hdr->Pe32));
- if (EFI_ERROR (Status) ||
BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) ||
Hdr->Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
- Status = EFI_LOAD_ERROR;
- DEBUG((DEBUG_ERROR, "%a(%d):error!\n", __FUNCTION__,__LINE__));
- goto ErrReadDos;
- }
+ErrReadDos:
- return Status;
+}
+/**
- 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 +EFIAPI +OsBootGetImageHeader (
- 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;
- BOOLEAN Condition = TRUE;//pclint
- Root = NULL;
- ThisFile = NULL;
- //
- // Handle the file system interface to the device
- //
- Status = gBS->HandleProtocol (
Device,
&gEfiSimpleFileSystemProtocolGuid,
(VOID *) &Volume
);
- if (EFI_ERROR (Status)) {
- DEBUG((DEBUG_ERROR, "%a(%d):error ret :%r !\n", __FUNCTION__,__LINE__,Status));
- goto Done;
- }
- Status = Volume->OpenVolume (
Volume,
&Root
);
- if (EFI_ERROR (Status)) {
- DEBUG((DEBUG_ERROR, "%a(%d):error ret :%r !\n", __FUNCTION__,__LINE__,Status));
Root = NULL;
goto Done;
- }
- if (Root == NULL) {
- Status = EFI_LOAD_ERROR;
- DEBUG((DEBUG_ERROR, "%a(%d):error ret :%r !\n", __FUNCTION__,__LINE__,Status));
- goto Done;
- }
- Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
- if (EFI_ERROR (Status)) {
- DEBUG((DEBUG_ERROR, "%a(%d):file not found ret :%r !\n", __FUNCTION__,__LINE__,Status));
- goto Done;
- }
- if (ThisFile == NULL) {
- DEBUG((DEBUG_ERROR, "%a(%d):error ret :%r !\n", __FUNCTION__,__LINE__,Status));
- Status = EFI_LOAD_ERROR;
- goto Done;
- }
- //
- // 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 (Condition);
- FileSize = Info->FileSize;
- FreePool (Info);
- Status = ReadDosHeader(ThisFile, FileSize, DosHeader, &Hdr);
- if (EFI_ERROR (Status)) {
- DEBUG((DEBUG_ERROR, "%a(%d):error ret :%r !\n", __FUNCTION__,__LINE__,Status));
- 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;
DEBUG((DEBUG_ERROR, "%a(%d):error ret :%r !\n", __FUNCTION__,__LINE__,Status));
goto Done;
- }
- Done:
- if (ThisFile != NULL) {
ThisFile->Close (ThisFile);
- }
- if (Root != NULL) {
Root->Close (Root);
- }
- return Status;
+}
+VOID +PrintDevicePath (
- CHAR16 *PreStr,
- EFI_DEVICE_PATH_PROTOCOL *Path
- )
+{
- CHAR16 *DevicePathTxt;
- EFI_STATUS Status;
- EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToTextProtocol;
- DevicePathTxt = NULL;
- Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
- if (!EFI_ERROR (Status)) {
- DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (Path, FALSE, TRUE);
- DEBUG ((DEBUG_ERROR, "%s DevPath:[%s]\n", PreStr, DevicePathTxt));
- }
- if (DevicePathTxt != NULL) {
- FreePool (DevicePathTxt);
- }
- return ;
+}
+CHAR16 * +GetGptNodeText (
- EFI_DEVICE_PATH_PROTOCOL *Path
- )
+{
- CHAR16 *NodeText;
- while (!IsDevicePathEnd (Path)) {
- NodeText = ConvertDeviceNodeToText (Path, TRUE, TRUE);
- if (StrStr (NodeText, L"GPT") != NULL) {
return NodeText;
- }
- if (NodeText != NULL) {
FreePool (NodeText);
- }
- Path = NextDevicePathNode (Path);
- }
- return NULL;
+}
+BOOLEAN +IsPartitionGuidEqual (
- EFI_DEVICE_PATH_PROTOCOL *OptionPath,
- EFI_DEVICE_PATH_PROTOCOL *FilePath
- )
+{
- CHAR16 *OptionGptText;
- CHAR16 *FileGptText;
- OptionGptText = GetGptNodeText (OptionPath);
- FileGptText = GetGptNodeText (FilePath);
- if ((OptionGptText != NULL) && (FileGptText != NULL) && (StrCmp (OptionGptText, FileGptText) == 0)) {
- return TRUE;
- }
- if (OptionGptText != NULL) {
- FreePool (OptionGptText);
- }
- if (FileGptText != NULL) {
- FreePool (FileGptText);
- }
- return FALSE;
+}
+/* If a partition exist a valid grub, OsBootLib will create a Option after bios firmware upgraded,
- and then installing the same OS on the same partition will create anothor Option. the two Options
- are superfluous, the Option added by OsBootLib should be remove.
- It's allowed of creating several Option in the same GPT by installing OS.
- */
+VOID +RemoveSuperfluousOption (
- EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions,
- UINT16 *OptionDelFlags,
- UINTN BootOptionCount
- )
+{
- EFI_STATUS Status;
- UINTN Index;
- for (Index = 1; Index < BootOptionCount; Index++) {
- if (OptionDelFlags[Index] == 0) {
if ((IsPartitionGuidEqual (BootOptions[0].FilePath, BootOptions[Index].FilePath)) &&
(IsOptionAddedByOsBootLib (BootOptions[Index].Description))) {
OptionDelFlags[Index] = 1;
Status = EfiBootManagerDeleteLoadOptionVariable (BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "DeleteLoadOptionVariable: %r\n", Status));
continue;
}
PrintDevicePath (L"Del Option(du),", BootOptions[Index].FilePath);
}
- }
- }
- return;
+}
+UINTN +GetOptionPositionWithoutGpt (
- VOID
- )
+{
- UINTN Index;
- UINTN BootOptionCount;
- EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
- BootOptions = EfiBootManagerGetLoadOptions (
&BootOptionCount, LoadOptionTypeBoot
);
- for (Index = 0; Index < BootOptionCount; Index++) {
- if (GetGptNodeText (BootOptions[Index].FilePath) == NULL) {
return Index;
- }
- }
- return 0;
+}
+CHAR16 * +GetFileTextByDevicePath (
- EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
+{
- CHAR16 *FileString;
- FileString = NULL;
- while (!IsDevicePathEnd (DevicePath)) {
- if (MEDIA_DEVICE_PATH == DevicePathType (DevicePath) &&
MEDIA_FILEPATH_DP == DevicePathSubType (DevicePath)) {
FileString = ConvertDeviceNodeToText (DevicePath, TRUE, TRUE);
break;
- }
- DevicePath = NextDevicePathNode (DevicePath);
- }
- return FileString;
+}
+/**
- Check same boot option by device path.
+*/ +BOOLEAN +BeHaveSameBootOptionByDP (
- EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- CHAR16 *FileName
- )
+{
- UINTN Index;
- UINTN ValidPathSize;
- BOOLEAN Found;
- EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
- UINTN BootOptionCount;
- if (NULL == DevicePath) {
- return FALSE;
- }
- BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
- Found = FALSE;
- for (Index = 0; Index < BootOptionCount; Index++) {
- /* If a partition exist a valid Option, then the new Option should not be added.
* After installation, some iso will create several valid grub file, like
* \EFI\centos\shimaa64.efi, \EFI\BOOT\BOOTAA64.EFI.
*/
- if(IsPartitionGuidEqual (BootOptions[Index].FilePath, DevicePath)) {
DEBUG ((DEBUG_ERROR, "Get the same Option(GPT).\n"));
Found = TRUE;
break;
- }
- /* If DevicePath of new Option is matched in exist Option and file name of
* new Option is EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64, then the new Option should be ignored.
*/
- ValidPathSize = GetDevicePathSize (BootOptions[Index].FilePath) - END_DEVICE_PATH_LENGTH;
- if ((CompareMem (BootOptions[Index].FilePath, DevicePath, ValidPathSize) == 0) &&
(StrCmp (FileName, EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64) == 0))
- {
DEBUG ((DEBUG_ERROR, "Get the same Option.\n"));
Found = TRUE;
break;
- }
- }
- EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
- return Found;
+}
+/**
- Check Os Boot Option if exist in current system.
+*/ +BOOLEAN +BeInvalidOsBootOption (
- EFI_DEVICE_PATH_PROTOCOL *OptionDp
- )
+{
- EFI_STATUS Status;
- EFI_HANDLE *FileSystemHandles;
- UINTN NumberFileSystemHandles;
- UINTN Index;
- EFI_DEVICE_PATH_PROTOCOL *FileSystemDP;
- UINTN OptionDpSize;
- EFI_BLOCK_IO_PROTOCOL *BlkIo;
- EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
- EFI_IMAGE_DOS_HEADER DosHeader;
- BOOLEAN Invalid;
- EFI_DEVICE_PATH_PROTOCOL* DevicePathNode;
- CHAR16 *FileString;
- Invalid = TRUE;
- if (NULL == OptionDp) {
- return FALSE;
- }
- OptionDpSize = GetDevicePathSize (OptionDp);
- if (OptionDpSize == 0) {
- return FALSE;
- }
- //
- // Os BootOption should be File Device Path.
- //
- DevicePathNode = OptionDp;
- FileString = GetFileTextByDevicePath (DevicePathNode);
- if (FileString == NULL) {
- return FALSE;
- }
- //
- // File should be exsiting in system.
- //
- Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&NumberFileSystemHandles,
&FileSystemHandles
);
- if (EFI_ERROR (Status)) {
- FreePool (FileString);
- return FALSE;
- }
- for (Index = 0; Index < NumberFileSystemHandles; Index++) {
- Status = gBS->HandleProtocol (
FileSystemHandles[Index],
&gEfiBlockIoProtocolGuid,
(VOID **) &BlkIo
);
- if (EFI_ERROR (Status)) {
continue;
- }
- FileSystemDP = FileDevicePath (FileSystemHandles[Index], FileString);
- /* If Partition is existed and the grub file is existed, then the Option is valid. */
- if ((CompareMem ((VOID *) OptionDp, (VOID *) FileSystemDP, OptionDpSize) == 0) ||
(IsPartitionGuidEqual (OptionDp, FileSystemDP))) {
Hdr.Union = &HdrData;
Status = OsBootGetImageHeader (
FileSystemHandles[Index],
FileString,
&DosHeader,
Hdr
);
if (!EFI_ERROR (Status) &&
EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
DEBUG ((DEBUG_ERROR, "BeValidOsBootOption (),Get Bootable file :%s.\n", FileString));
Invalid = FALSE;
break;
}
- }
- if (FileSystemDP != NULL) {
FreePool (FileSystemDP);
- }
- }
- if (NumberFileSystemHandles != 0) {
- FreePool (FileSystemHandles);
- }
- if (FileString != NULL) {
- FreePool (FileString);
- }
- return Invalid;
+}
diff --git a/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.c b/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.c index 845519f..1c6e8bf 100644 --- a/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.c +++ b/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.c @@ -18,6 +18,7 @@ #include <IndustryStandard/Pci22.h> #include <Library/BmcConfigBootLib.h> #include <Library/DevicePathLib.h> +#include <Library/OsBootLib.h> #include <Library/PcdLib.h> #include <Library/UefiBootManagerLib.h> #include <Library/UefiLib.h> @@ -576,6 +577,11 @@ PlatformBootManagerAfterConsole ( PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE );
- Status = AdjustOsBootOrder ();
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a:%r\n", __FUNCTION__, Status));
- }
- HandleBmcBootType ();
}
diff --git a/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf index 7b151a9..a6d597d 100644 --- a/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf +++ b/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf @@ -49,6 +49,7 @@ DevicePathLib DxeServicesLib MemoryAllocationLib
- OsBootLib PcdLib PrintLib UefiBootManagerLib
-- 1.9.1