From nobody Mon Dec 23 18:10:38 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1516287780594217.12053223200007; Thu, 18 Jan 2018 07:03:00 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id A37702238B58C; Thu, 18 Jan 2018 06:57:12 -0800 (PST) Received: from mail-pf0-x242.google.com (mail-pf0-x242.google.com [IPv6:2607:f8b0:400e:c00::242]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 312D12238B582 for ; Thu, 18 Jan 2018 06:57:11 -0800 (PST) Received: by mail-pf0-x242.google.com with SMTP id y5so14791261pff.13 for ; Thu, 18 Jan 2018 07:02:32 -0800 (PST) Received: from localhost.localdomain ([120.31.149.194]) by smtp.gmail.com with ESMTPSA id j14sm13621815pfh.94.2018.01.18.07.02.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 18 Jan 2018 07:02:31 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:400e:c00::242; helo=mail-pf0-x242.google.com; envelope-from=heyi.guo@linaro.org; receiver=edk2-devel@lists.01.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=F+9tv0xyBK0I+zatElu7Bwl09HI8InxiyOSkH3VaEzg=; b=eFFII/OjS+1C/rjO6hoqMaWiE63Ss53KebnbI10OhLbb04GskdPMTqYAY2LFfXWvuR 3RQzFh1VIQFYoZ2Y1ko5UjvJi8TCj0HMqEDeoIdy4rdDwH4cU0XN67oKX53Su9UDf9e0 TvlP3ODiLap4EQcwmiXV1LVhUFnPOu1D4hUjE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=F+9tv0xyBK0I+zatElu7Bwl09HI8InxiyOSkH3VaEzg=; b=AmJtSyqkWhfPExOBsSWEHQM87JBrjqCqVfTPuzjIlJg1B44+mTf1775zwM2cwQsFHu jtuCnW7uXjiyaPm9Mv2euvo1zGT73dTQ9dZpUi2n1PCa7TG1qA2uCEg6YwXIJ0J1E8ks yiKQMPlIc4Rl7YXdnLm6wGUjZ6uAy1VDEuzHd6tsVxb+iroMf+/uEkfFmxQLZ4/gg5gD 1QRVur1poxbIRCHwMpBdLslLNyAsJpcQGWdTDQWyttiUAGhkt3R6M9nREo/qn8M4LxHO B4q2HtzGVHSvuMyR0pAG72zBpCWH/z/MmY9yDrI06QUtvXZe4Di5KNuJMFVUkBytBkZy lcAg== X-Gm-Message-State: AKwxyteBu1byowQxQsP1pD1w0mEMD5qve0tbU3JiaIIbZMdRODtfNx89 e7+4Bveo0X7+OxrMYkVEfg3KVg== X-Google-Smtp-Source: ACJfBos3e0oym0rGFK0rn0PECvGeAC99oAiaSWVX+tI002q5vRJg4/fexVuTTwCjAjFFgEsh0MCrbQ== X-Received: by 10.99.147.70 with SMTP id w6mr1765295pgm.410.1516287752265; Thu, 18 Jan 2018 07:02:32 -0800 (PST) From: Ming Huang X-Google-Original-From: Ming Huang To: leif.lindholm@linaro.org, linaro-uefi@lists.linaro.org, edk2-devel@lists.01.org, graeme.gregory@linaro.org Date: Thu, 18 Jan 2018 23:01:42 +0800 Message-Id: <1516287703-35516-14-git-send-email-huangming23@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1516287703-35516-1-git-send-email-huangming23@huawei.com> References: <1516287703-35516-1-git-send-email-huangming23@huawei.com> Subject: [edk2] [PATCH edk2-platforms v1 13/14] Hisilicon/Library: Add OsBootLib X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: huangming23@huawei.com, ard.biesheuvel@linaro.org, zhangjinsong2@huawei.com, Heyi Guo , wanghuiqiang@huawei.com, guoheyi@huawei.com, waip23@126.com, mengfanrong@huawei.com MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" OsBootLib can create OS option after upgrade firmware. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ming Huang Signed-off-by: Heyi Guo --- 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.in= f | 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/UefiHiiServic= esLib.inf UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf + OsBootLib|Silicon/Hisilicon/Library/OsBootLib/OsBootLib.inf =20 =20 =20 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 =20 !if $(NETWORK_IP6_ENABLE) =3D=3D TRUE TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf diff --git a/Silicon/Hisilicon/Include/Library/OsBootLib.h b/Silicon/Hisili= con/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 B= SD 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 IM= PLIED. +* +**/ + +#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 list= ed 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/Hisilic= on/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 B= SD 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 IM= PLIED. +* +**/ + +#ifndef _OS_BOOT_H_ +#define _OS_BOOT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +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, PE= 32+, 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/Hisi= licon/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 B= SD 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 IM= PLIED. +* +**/ + +#include "OsBoot.h" + +UEFI_OS_BOOT_FILE mUefiOsBootFiles[] =3D { + {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 Boo= t"}, + {L"\\EFI\\ubuntu\\grubx64.efi", L"Uefi Ubuntu Grubx64 Boo= t"}, + {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 =3D 0; Index < (sizeof (mUefiOsBootFiles) / sizeof (UEFI_OS_B= OOT_FILE)); Index++) { + if (StrCmp (mUefiOsBootFiles[Index].Description, OptionDescription) = =3D=3D 0) { + return TRUE; + } + } + + return FALSE; +} + +/** + Remove invalid OS boot options, and then add new ones. + +*/ +EFI_STATUS +AdjustOsBootOrder ( + VOID + ) +{ + EFI_STATUS Status; + + Status =3D RemoveInvalidOsBootOptions (); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D 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 =3D EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOpti= onTypeBoot); + OptionDelFlags =3D AllocateZeroPool (BootOptionCount * sizeof(UINT16)); + if (OptionDelFlags =3D=3D NULL) { + goto exit; + } + + for (Index =3D 0; Index < BootOptionCount; Index++) { + if (OptionDelFlags[Index] =3D=3D 0) { + if (BeInvalidOsBootOption (BootOptions[Index].FilePath)) { + Status =3D EfiBootManagerDeleteLoadOptionVariable (BootOptions[Ind= ex].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, Boot= OptionCount - Index); + } + } + } + + exit: + if (OptionDelFlags !=3D NULL) { + FreePool (OptionDelFlags); + } + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); + + return EFI_SUCCESS; +} + + +/** + Try to find UEFI OSs and create the boot options which haven't been list= ed 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 =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &NumberFileSystemHandles, + &FileSystemHandles + ); + if (EFI_ERROR (Status)) { + return Status; + } + + MaxFiles =3D sizeof (mUefiOsBootFiles) / sizeof (UEFI_OS_BOOT_FILE); + for (Index =3D 0; Index < NumberFileSystemHandles; Index++) { + Status =3D gBS->HandleProtocol ( + FileSystemHandles[Index], + &gEfiBlockIoProtocolGuid, + (VOID **) &BlkIo + ); + if (EFI_ERROR (Status)) { + continue; + } + + Hdr.Union =3D &HdrData; + for (Count =3D 0; Count < MaxFiles; Count++) { + // + //Read Boot File Path to check validation. + // + Status =3D 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 =3D=3D EFI_IMAGE_SUBSYSTEM_EF= I_APPLICATION) { + + OsFileDP =3D NULL; + OsFileDP =3D FileDevicePath (FileSystemHandles[Index], mUefiOsBoot= Files[Count].FilePathString); + PrintDevicePath (L"Exist", OsFileDP); + if (!BeHaveSameBootOptionByDP (OsFileDP, mUefiOsBootFiles[Count].F= ilePathString)) { + // + // Create new BootOption if it is not present. + // + DEBUG ((DEBUG_INFO, "CreateOsBootOptions (), Make New Boot Optio= n :%s.\n", mUefiOsBootFiles[Count].Description)); + Status =3D EfiBootManagerInitializeLoadOption ( + &NewOption, + LoadOptionNumberUnassigned, + LoadOptionTypeBoot, + LOAD_OPTION_ACTIVE, + mUefiOsBootFiles[Count].Description, + OsFileDP, + NULL, + 0 + ); + ASSERT_EFI_ERROR (Status); + Status =3D EfiBootManagerAddLoadOptionVariable (&NewOption, GetO= ptionPositionWithoutGpt ()); + ASSERT_EFI_ERROR (Status); + EfiBootManagerFreeLoadOption (&NewOption); + } + + if(OsFileDP !=3D NULL) { + FreePool (OsFileDP); + OsFileDP =3D NULL; + } + } + } + } + + if (NumberFileSystemHandles !=3D 0) { + FreePool (FileSystemHandles); + } + + return EFI_SUCCESS; +} + diff --git a/Silicon/Hisilicon/Library/OsBootLib/OsBootLib.inf b/Silicon/Hi= silicon/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.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD 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 IM= PLIED. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D OsBootLib + FILE_GUID =3D e406c654-ccde-4d32-8362-0aec01725139 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D 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 ## G= UID + +[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 B= SD 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 IM= PLIED. +* +**/ + +#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, PE= 32+, 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 =3D sizeof (EFI_IMAGE_DOS_HEADER); + Status =3D ThisFile->Read (ThisFile, &BufferSize, DosHeader); + if (EFI_ERROR (Status) || + BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) || + FileSize <=3D DosHeader->e_lfanew || + DosHeader->e_magic !=3D EFI_IMAGE_DOS_SIGNATURE) { + Status =3D EFI_LOAD_ERROR; + DEBUG ((DEBUG_ERROR, "%a(%d):error!\n", __FUNCTION__,__LINE__)); + goto ErrReadDos; + } + + // + // Move to PE signature + // + Status =3D ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew); + if (EFI_ERROR (Status)) { + Status =3D EFI_LOAD_ERROR; + DEBUG((DEBUG_ERROR, "%a(%d):error!\n", __FUNCTION__,__LINE__)); + goto ErrReadDos; + } + + // + // Read and check PE signature + // + BufferSize =3D sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); + Status =3D ThisFile->Read (ThisFile, &BufferSize, (VOID*)(Hdr->Pe32)); + if (EFI_ERROR (Status) || + BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) || + Hdr->Pe32->Signature !=3D EFI_IMAGE_NT_SIGNATURE) { + Status =3D 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, PE= 32+, 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 =3D TRUE;//pclint + + Root =3D NULL; + ThisFile =3D NULL; + // + // Handle the file system interface to the device + // + Status =3D 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 =3D Volume->OpenVolume ( + Volume, + &Root + ); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "%a(%d):error ret :%r !\n", __FUNCTION__,__LINE__,= Status)); + Root =3D NULL; + goto Done; + } + + if (Root =3D=3D NULL) { + Status =3D EFI_LOAD_ERROR; + DEBUG((DEBUG_ERROR, "%a(%d):error ret :%r !\n", __FUNCTION__,__LINE__,= Status)); + goto Done; + } + Status =3D 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 =3D=3D NULL) { + DEBUG((DEBUG_ERROR, "%a(%d):error ret :%r !\n", __FUNCTION__,__LINE__,= Status)); + Status =3D EFI_LOAD_ERROR; + goto Done; + } + // + // Get file size + // + BufferSize =3D SIZE_OF_EFI_FILE_INFO + 200; + do { + Info =3D NULL; + Status =3D gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOI= D **) &Info); + if (EFI_ERROR (Status)) { + goto Done; + } + Status =3D ThisFile->GetInfo ( + ThisFile, + &gEfiFileInfoGuid, + &BufferSize, + Info + ); + if (!EFI_ERROR (Status)) { + break; + } + if (Status !=3D EFI_BUFFER_TOO_SMALL) { + FreePool (Info); + goto Done; + } + FreePool (Info); + } while (Condition); + + FileSize =3D Info->FileSize; + FreePool (Info); + + Status =3D 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 !=3D EFI_IMAGE_NT_OPTIONAL_HDR32_MAGI= C && + Hdr.Pe32->OptionalHeader.Magic !=3D EFI_IMAGE_NT_OPTIONAL_HDR64_MAG= IC) { + Status =3D EFI_LOAD_ERROR; + DEBUG((DEBUG_ERROR, "%a(%d):error ret :%r !\n", __FUNCTION__,__LINE= __,Status)); + goto Done; + } + + Done: + if (ThisFile !=3D NULL) { + ThisFile->Close (ThisFile); + } + if (Root !=3D 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 =3D NULL; + Status =3D gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL,= (VOID **)&DevicePathToTextProtocol); + if (!EFI_ERROR (Status)) { + DevicePathTxt =3D DevicePathToTextProtocol->ConvertDevicePathToText (P= ath, FALSE, TRUE); + DEBUG ((DEBUG_ERROR, "%s DevPath:[%s]\n", PreStr, DevicePathTxt)); + } + + if (DevicePathTxt !=3D NULL) { + FreePool (DevicePathTxt); + } + + return ; +} + +CHAR16 * +GetGptNodeText ( + EFI_DEVICE_PATH_PROTOCOL *Path + ) +{ + CHAR16 *NodeText; + + while (!IsDevicePathEnd (Path)) { + NodeText =3D ConvertDeviceNodeToText (Path, TRUE, TRUE); + if (StrStr (NodeText, L"GPT") !=3D NULL) { + return NodeText; + } + + if (NodeText !=3D NULL) { + FreePool (NodeText); + } + + Path =3D NextDevicePathNode (Path); + } + + return NULL; +} + +BOOLEAN +IsPartitionGuidEqual ( + EFI_DEVICE_PATH_PROTOCOL *OptionPath, + EFI_DEVICE_PATH_PROTOCOL *FilePath + ) +{ + CHAR16 *OptionGptText; + CHAR16 *FileGptText; + + OptionGptText =3D GetGptNodeText (OptionPath); + FileGptText =3D GetGptNodeText (FilePath); + if ((OptionGptText !=3D NULL) && (FileGptText !=3D NULL) && (StrCmp (Opt= ionGptText, FileGptText) =3D=3D 0)) { + return TRUE; + } + + if (OptionGptText !=3D NULL) { + FreePool (OptionGptText); + } + if (FileGptText !=3D 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 anoth= or 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 O= S. + */ +VOID +RemoveSuperfluousOption ( + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions, + UINT16 *OptionDelFlags, + UINTN BootOptionCount + ) +{ + EFI_STATUS Status; + UINTN Index; + + for (Index =3D 1; Index < BootOptionCount; Index++) { + if (OptionDelFlags[Index] =3D=3D 0) { + if ((IsPartitionGuidEqual (BootOptions[0].FilePath, BootOptions[Inde= x].FilePath)) && + (IsOptionAddedByOsBootLib (BootOptions[Index].Description))) { + OptionDelFlags[Index] =3D 1; + + Status =3D EfiBootManagerDeleteLoadOptionVariable (BootOptions[Ind= ex].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 =3D EfiBootManagerGetLoadOptions ( + &BootOptionCount, LoadOptionTypeBoot + ); + for (Index =3D 0; Index < BootOptionCount; Index++) { + if (GetGptNodeText (BootOptions[Index].FilePath) =3D=3D NULL) { + return Index; + } + } + + return 0; +} + +CHAR16 * +GetFileTextByDevicePath ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + CHAR16 *FileString; + + FileString =3D NULL; + + while (!IsDevicePathEnd (DevicePath)) { + if (MEDIA_DEVICE_PATH =3D=3D DevicePathType (DevicePath) && + MEDIA_FILEPATH_DP =3D=3D DevicePathSubType (DevicePath)) { + FileString =3D ConvertDeviceNodeToText (DevicePath, TRUE, TRUE); + break; + } + DevicePath =3D 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 =3D=3D DevicePath) { + return FALSE; + } + + BootOptions =3D EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOpti= onTypeBoot); + + Found =3D FALSE; + for (Index =3D 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, l= ike + * \EFI\centos\shimaa64.efi, \EFI\BOOT\BOOTAA64.EFI. + */ + if(IsPartitionGuidEqual (BootOptions[Index].FilePath, DevicePath)) { + DEBUG ((DEBUG_ERROR, "Get the same Option(GPT).\n")); + Found =3D TRUE; + break; + } + + /* If DevicePath of new Option is matched in exist Option and file nam= e of + * new Option is EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64, then the new O= ption should be ignored. + */ + ValidPathSize =3D GetDevicePathSize (BootOptions[Index].FilePath) - EN= D_DEVICE_PATH_LENGTH; + if ((CompareMem (BootOptions[Index].FilePath, DevicePath, ValidPathSi= ze) =3D=3D 0) && + (StrCmp (FileName, EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64) =3D=3D 0= )) + { + DEBUG ((DEBUG_ERROR, "Get the same Option.\n")); + Found =3D 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 =3D TRUE; + if (NULL =3D=3D OptionDp) { + return FALSE; + } + + OptionDpSize =3D GetDevicePathSize (OptionDp); + if (OptionDpSize =3D=3D 0) { + return FALSE; + } + + // + // Os BootOption should be File Device Path. + // + DevicePathNode =3D OptionDp; + FileString =3D GetFileTextByDevicePath (DevicePathNode); + if (FileString =3D=3D NULL) { + return FALSE; + } + + // + // File should be exsiting in system. + // + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &NumberFileSystemHandles, + &FileSystemHandles + ); + if (EFI_ERROR (Status)) { + FreePool (FileString); + return FALSE; + } + + for (Index =3D 0; Index < NumberFileSystemHandles; Index++) { + Status =3D gBS->HandleProtocol ( + FileSystemHandles[Index], + &gEfiBlockIoProtocolGuid, + (VOID **) &BlkIo + ); + if (EFI_ERROR (Status)) { + continue; + } + + FileSystemDP =3D FileDevicePath (FileSystemHandles[Index], FileString); + /* If Partition is existed and the grub file is existed, then the Opti= on is valid. */ + if ((CompareMem ((VOID *) OptionDp, (VOID *) FileSystemDP, OptionDpSiz= e) =3D=3D 0) || + (IsPartitionGuidEqual (OptionDp, FileSystemDP))) { + Hdr.Union =3D &HdrData; + Status =3D OsBootGetImageHeader ( + FileSystemHandles[Index], + FileString, + &DosHeader, + Hdr + ); + if (!EFI_ERROR (Status) && + EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) = && + Hdr.Pe32->OptionalHeader.Subsystem =3D=3D EFI_IMAGE_SUBSYSTEM_EF= I_APPLICATION) { + DEBUG ((DEBUG_ERROR, "BeValidOsBootOption (),Get Bootable file :%s= .\n", FileString)); + Invalid =3D FALSE; + break; + } + } + + if (FileSystemDP !=3D NULL) { + FreePool (FileSystemDP); + } + } + + if (NumberFileSystemHandles !=3D 0) { + FreePool (FileSystemHandles); + } + if (FileString !=3D 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 #include #include +#include #include #include #include @@ -576,6 +577,11 @@ PlatformBootManagerAfterConsole ( PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE ); =20 + Status =3D AdjustOsBootOrder (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a:%r\n", __FUNCTION__, Status)); + } + HandleBmcBootType (); } =20 diff --git a/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBootM= anagerLib.inf b/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBo= otManagerLib.inf index 7b151a9..a6d597d 100644 --- a/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerL= ib.inf +++ b/Silicon/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerL= ib.inf @@ -49,6 +49,7 @@ DevicePathLib DxeServicesLib MemoryAllocationLib + OsBootLib PcdLib PrintLib UefiBootManagerLib --=20 1.9.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel