From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Ming Huang <heyi.guo@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>,
linaro-uefi <linaro-uefi@lists.linaro.org>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
Graeme Gregory <graeme.gregory@linaro.org>,
guoheyi@huawei.com, wanghuiqiang <wanghuiqiang@huawei.com>,
huangming <huangming23@huawei.com>,
Jason Zhang <zhangjinsong2@huawei.com>,
Mengfanrong <mengfanrong@huawei.com>,
waip23@126.com
Subject: Re: [PATCH edk2-platforms v1 13/14] Hisilicon/Library: Add OsBootLib
Date: Sat, 20 Jan 2018 11:11:14 +0000 [thread overview]
Message-ID: <CAKv+Gu8tn5oLtbe9K0b-4U1uMFLP2=-yMZPbZt5JUYyo-7ziMQ@mail.gmail.com> (raw)
In-Reply-To: <1516287703-35516-14-git-send-email-huangming23@huawei.com>
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
>
next prev parent reply other threads:[~2018-01-20 11:05 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-18 15:01 [PATCH edk2-platforms v1 00/14] Improve D0x platforms and bug fix Ming Huang
2018-01-18 15:01 ` [PATCH edk2-platforms v1 01/14] Hisilicon/D05: Add PPTT support Ming Huang
2018-01-20 10:16 ` Ard Biesheuvel
2018-01-22 9:16 ` Huangming (Mark)
2018-01-23 6:00 ` Huangming (Mark)
2018-01-22 13:53 ` Leif Lindholm
2018-01-22 14:15 ` Leif Lindholm
2018-01-24 13:49 ` graeme.gregory
2018-01-23 21:29 ` Jeremy Linton
2018-01-24 7:57 ` Huangming (Mark)
2018-01-25 5:56 ` Huangming (Mark)
2018-01-25 15:27 ` Jeremy Linton
2018-01-18 15:01 ` [PATCH edk2-platforms v1 02/14] Hisilicon D03/D05:Switch to Generic BDS driver Ming Huang
2018-01-20 10:27 ` Ard Biesheuvel
2018-01-22 18:38 ` Leif Lindholm
2018-01-23 6:03 ` Huangming (Mark)
2018-01-18 15:01 ` [PATCH edk2-platforms v1 03/14] Hisilicon D03/D05: Optimize the feature of BMC set boot option Ming Huang
2018-01-20 10:41 ` Ard Biesheuvel
2018-01-23 8:28 ` Huangming (Mark)
2018-01-23 10:28 ` Leif Lindholm
2018-01-23 10:51 ` Huangming (Mark)
2018-01-18 15:01 ` [PATCH edk2-platforms v1 04/14] Hisilicon D03/D05: Add capsule upgrade support Ming Huang
2018-01-20 10:50 ` Ard Biesheuvel
2018-01-23 8:53 ` Huangming (Mark)
2018-01-23 9:33 ` Ard Biesheuvel
2018-01-24 11:10 ` Huangming (Mark)
2018-01-24 11:21 ` Ard Biesheuvel
2018-01-25 0:53 ` Huangming (Mark)
2018-01-23 14:06 ` Leif Lindholm
2018-01-18 15:01 ` [PATCH edk2-platforms v1 05/14] Hisilicon D03/D05: Open SasPlatform source code Ming Huang
2018-01-20 10:57 ` Ard Biesheuvel
2018-01-23 11:01 ` Huangming (Mark)
2018-01-23 14:04 ` Leif Lindholm
2018-01-18 15:01 ` [PATCH edk2-platforms v1 06/14] Hisilicon D03/D05: Open SnpPlatform " Ming Huang
2018-01-20 11:00 ` Ard Biesheuvel
2018-01-23 11:01 ` Huangming (Mark)
2018-01-23 14:07 ` Leif Lindholm
2018-01-24 12:31 ` Huangming (Mark)
2018-01-24 13:47 ` Leif Lindholm
2018-01-18 15:01 ` [PATCH edk2-platforms v1 07/14] Hisilicon/Smbios: modify type 4 Ming Huang
2018-01-20 11:01 ` Ard Biesheuvel
2018-01-23 14:15 ` Leif Lindholm
2018-01-18 15:01 ` [PATCH edk2-platforms v1 08/14] Hisilicon/PCIe: Disable PCIe ASPM Ming Huang
2018-01-20 11:04 ` Ard Biesheuvel
2018-01-18 15:01 ` [PATCH edk2-platforms v1 09/14] Hisilicon/D05: Replace SP805Watchdog by WatchdogTimer driver Ming Huang
2018-01-20 11:05 ` Ard Biesheuvel
2018-01-23 14:21 ` Leif Lindholm
2018-01-18 15:01 ` [PATCH edk2-platforms v1 10/14] Hisilicon/D03: " Ming Huang
2018-01-20 11:05 ` Ard Biesheuvel
2018-01-23 14:21 ` Leif Lindholm
2018-01-18 15:01 ` [PATCH edk2-platforms v1 11/14] Hisilicon/D05/ACPI: Add ITS PXM Ming Huang
2018-01-20 11:06 ` Ard Biesheuvel
2018-01-18 15:01 ` [PATCH edk2-platforms v1 12/14] Hisilicon/D05/ACPI: Add Pcie, HNS and SAS PXM Ming Huang
2018-01-20 11:08 ` Ard Biesheuvel
2018-01-18 15:01 ` [PATCH edk2-platforms v1 13/14] Hisilicon/Library: Add OsBootLib Ming Huang
2018-01-20 11:11 ` Ard Biesheuvel [this message]
2018-01-23 10:23 ` Leif Lindholm
2018-01-27 1:47 ` Huangming (Mark)
2018-01-27 10:37 ` Ard Biesheuvel
2018-01-29 8:55 ` Huangming (Mark)
2018-01-29 10:19 ` Ard Biesheuvel
2018-01-29 11:16 ` Leif Lindholm
2018-02-07 21:16 ` Peter Jones
2018-02-11 6:03 ` Huangming (Mark)
2018-02-26 1:12 ` Guo Heyi
2018-01-18 15:01 ` [PATCH edk2-platforms v1 14/14] Hisilicon D03/D05: Update firmware version to 18.02 Ming Huang
2018-01-20 11:11 ` Ard Biesheuvel
2018-01-23 10:18 ` Leif Lindholm
2018-01-24 1:17 ` Huangming (Mark)
2018-01-24 7:54 ` Leif Lindholm
2018-01-22 13:26 ` [PATCH edk2-platforms v1 00/14] Improve D0x platforms and bug fix Leif Lindholm
2018-01-23 14:24 ` Leif Lindholm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAKv+Gu8tn5oLtbe9K0b-4U1uMFLP2=-yMZPbZt5JUYyo-7ziMQ@mail.gmail.com' \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox