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