* [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3
@ 2019-01-29 5:27 Chen A Chen
2019-01-29 5:27 ` [PATCH v3 1/3] FatPkg: Break down Part.c file Chen A Chen
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Chen A Chen @ 2019-01-29 5:27 UTC (permalink / raw)
To: edk2-devel
No function change, fix code style issue.
Chen A Chen (3):
FatPkg: Break down Part.c file.
MdePkg/UefiGpt.h: Add new definition for enable GPT support
FatPkg: Add GPT check in FatPei to support Capsule-on-Disk feature.
FatPkg/FatPei/Eltorito.c | 239 ++++++++++++++++++
FatPkg/FatPei/FatLitePeim.h | 3 +-
FatPkg/FatPei/FatPei.inf | 7 +-
FatPkg/FatPei/Gpt.c | 548 ++++++++++++++++++++++++++++++++++++++++++
FatPkg/FatPei/Mbr.c | 181 ++++++++++++++
FatPkg/FatPei/Part.c | 434 +++------------------------------
MdePkg/Include/Uefi/UefiGpt.h | 6 +-
7 files changed, 1020 insertions(+), 398 deletions(-)
create mode 100644 FatPkg/FatPei/Eltorito.c
create mode 100644 FatPkg/FatPei/Gpt.c
create mode 100644 FatPkg/FatPei/Mbr.c
--
2.16.2.windows.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/3] FatPkg: Break down Part.c file.
2019-01-29 5:27 [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3 Chen A Chen
@ 2019-01-29 5:27 ` Chen A Chen
2019-01-29 5:27 ` [PATCH v3 2/3] MdePkg/UefiGpt.h: Add new definition for enable GPT support Chen A Chen
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Chen A Chen @ 2019-01-29 5:27 UTC (permalink / raw)
To: edk2-devel; +Cc: Chen A Chen, Ruiyu Ni, Zhang Chao B
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1470
Break down partition parsing logic to 2 parts, Eltorito and MBR.
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Zhang Chao B <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
---
FatPkg/FatPei/Eltorito.c | 239 ++++++++++++++++++++++++++++
FatPkg/FatPei/FatPei.inf | 4 +-
FatPkg/FatPei/Mbr.c | 181 +++++++++++++++++++++
FatPkg/FatPei/Part.c | 402 ++---------------------------------------------
4 files changed, 432 insertions(+), 394 deletions(-)
create mode 100644 FatPkg/FatPei/Eltorito.c
create mode 100644 FatPkg/FatPei/Mbr.c
diff --git a/FatPkg/FatPei/Eltorito.c b/FatPkg/FatPei/Eltorito.c
new file mode 100644
index 0000000000..a350237bd3
--- /dev/null
+++ b/FatPkg/FatPei/Eltorito.c
@@ -0,0 +1,239 @@
+/** @file
+ Routines supporting partition discovery and
+ logical device reading
+
+Copyright (c) 2006 - 2019, 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.
+
+**/
+
+#include <IndustryStandard/ElTorito.h>
+#include "FatLitePeim.h"
+
+/**
+ This function finds Eltorito partitions. Main algorithm
+ is ported from DXE partition driver.
+
+ @param[in] PrivateData The global memory map
+ @param[in] ParentBlockDevNo The parent block device
+
+ @retval TRUE New partitions are detected and logical block devices
+ are added to block device array
+ @retval FALSE No new partitions are added
+
+**/
+BOOLEAN
+FatFindEltoritoPartitions (
+ IN PEI_FAT_PRIVATE_DATA *PrivateData,
+ IN UINTN ParentBlockDevNo
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN Found;
+ PEI_FAT_BLOCK_DEVICE *BlockDev;
+ PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
+ UINT32 VolDescriptorLba;
+ UINT32 Lba;
+ CDROM_VOLUME_DESCRIPTOR *VolDescriptor;
+ ELTORITO_CATALOG *Catalog;
+ UINTN Check;
+ UINTN Index;
+ UINTN MaxIndex;
+ UINT16 *CheckBuffer;
+ UINT32 SubBlockSize;
+ UINT32 SectorCount;
+ UINT32 VolSpaceSize;
+
+ if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
+ return FALSE;
+ }
+
+ Found = FALSE;
+ ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
+ VolSpaceSize = 0;
+
+ //
+ // CD_ROM has the fixed block size as 2048 bytes
+ //
+ if (ParentBlockDev->BlockSize != 2048) {
+ return FALSE;
+ }
+
+ VolDescriptor = (CDROM_VOLUME_DESCRIPTOR *) PrivateData->BlockData;
+ Catalog = (ELTORITO_CATALOG *) VolDescriptor;
+
+ //
+ // the ISO-9660 volume descriptor starts at 32k on the media
+ // and CD_ROM has the fixed block size as 2048 bytes, so...
+ //
+ VolDescriptorLba = 15;
+ //
+ // ((16*2048) / Media->BlockSize) - 1;
+ //
+ // Loop: handle one volume descriptor per time
+ //
+ while (TRUE) {
+
+ VolDescriptorLba += 1;
+ if (VolDescriptorLba > ParentBlockDev->LastBlock) {
+ //
+ // We are pointing past the end of the device so exit
+ //
+ break;
+ }
+
+ Status = FatReadBlock (
+ PrivateData,
+ ParentBlockDevNo,
+ VolDescriptorLba,
+ ParentBlockDev->BlockSize,
+ VolDescriptor
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ //
+ // Check for valid volume descriptor signature
+ //
+ if (VolDescriptor->Unknown.Type == CDVOL_TYPE_END ||
+ CompareMem (VolDescriptor->Unknown.Id, CDVOL_ID, sizeof (VolDescriptor->Unknown.Id)) != 0
+ ) {
+ //
+ // end of Volume descriptor list
+ //
+ break;
+ }
+ //
+ // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte
+ //
+ if (VolDescriptor->Unknown.Type == CDVOL_TYPE_CODED) {
+ VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[1];
+ }
+ //
+ // Is it an El Torito volume descriptor?
+ //
+ if (CompareMem (
+ VolDescriptor->BootRecordVolume.SystemId,
+ CDVOL_ELTORITO_ID,
+ sizeof (CDVOL_ELTORITO_ID) - 1
+ ) != 0) {
+ continue;
+ }
+ //
+ // Read in the boot El Torito boot catalog
+ //
+ Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);
+ if (Lba > ParentBlockDev->LastBlock) {
+ continue;
+ }
+
+ Status = FatReadBlock (
+ PrivateData,
+ ParentBlockDevNo,
+ Lba,
+ ParentBlockDev->BlockSize,
+ Catalog
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ //
+ // We don't care too much about the Catalog header's contents, but we do want
+ // to make sure it looks like a Catalog header
+ //
+ if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {
+ continue;
+ }
+
+ Check = 0;
+ CheckBuffer = (UINT16 *) Catalog;
+ for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {
+ Check += CheckBuffer[Index];
+ }
+
+ if ((Check & 0xFFFF) != 0) {
+ continue;
+ }
+
+ MaxIndex = ParentBlockDev->BlockSize / sizeof (ELTORITO_CATALOG);
+ for (Index = 1; Index < MaxIndex; Index += 1) {
+ //
+ // Next entry
+ //
+ Catalog += 1;
+
+ //
+ // Check this entry
+ //
+ if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {
+ continue;
+ }
+
+ SubBlockSize = 512;
+ SectorCount = Catalog->Boot.SectorCount;
+
+ switch (Catalog->Boot.MediaType) {
+
+ case ELTORITO_NO_EMULATION:
+ SubBlockSize = ParentBlockDev->BlockSize;
+ SectorCount = Catalog->Boot.SectorCount;
+ break;
+
+ case ELTORITO_HARD_DISK:
+ break;
+
+ case ELTORITO_12_DISKETTE:
+ SectorCount = 0x50 * 0x02 * 0x0F;
+ break;
+
+ case ELTORITO_14_DISKETTE:
+ SectorCount = 0x50 * 0x02 * 0x12;
+ break;
+
+ case ELTORITO_28_DISKETTE:
+ SectorCount = 0x50 * 0x02 * 0x24;
+ break;
+
+ default:
+ SectorCount = 0;
+ SubBlockSize = ParentBlockDev->BlockSize;
+ break;
+ }
+
+ if (SectorCount < 2) {
+ SectorCount = (VolSpaceSize > ParentBlockDev->LastBlock + 1) ? (UINT32) (ParentBlockDev->LastBlock - Catalog->Boot.Lba + 1) : (UINT32) (VolSpaceSize - Catalog->Boot.Lba);
+ }
+ //
+ // Register this partition
+ //
+ if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {
+
+ Found = TRUE;
+
+ BlockDev = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);
+
+ BlockDev->BlockSize = SubBlockSize;
+ BlockDev->LastBlock = SectorCount - 1;
+ BlockDev->IoAlign = ParentBlockDev->IoAlign;
+ BlockDev->Logical = TRUE;
+ BlockDev->PartitionChecked = FALSE;
+ BlockDev->StartingPos = MultU64x32 (Catalog->Boot.Lba, ParentBlockDev->BlockSize);
+ BlockDev->ParentDevNo = ParentBlockDevNo;
+
+ PrivateData->BlockDeviceCount++;
+ }
+ }
+ }
+
+ ParentBlockDev->PartitionChecked = TRUE;
+
+ return Found;
+
+}
diff --git a/FatPkg/FatPei/FatPei.inf b/FatPkg/FatPei/FatPei.inf
index fc8d612283..57312a9047 100644
--- a/FatPkg/FatPei/FatPei.inf
+++ b/FatPkg/FatPei/FatPei.inf
@@ -1,7 +1,7 @@
## @file
# Lite Fat driver only used in Pei Phase.
#
-# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2019, 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
@@ -30,6 +30,8 @@
#
[Sources]
+ Mbr.c
+ Eltorito.c
Part.c
FatLiteApi.c
FatLiteLib.c
diff --git a/FatPkg/FatPei/Mbr.c b/FatPkg/FatPei/Mbr.c
new file mode 100644
index 0000000000..acad6e7c13
--- /dev/null
+++ b/FatPkg/FatPei/Mbr.c
@@ -0,0 +1,181 @@
+/** @file
+ Routines supporting partition discovery and
+ logical device reading
+
+Copyright (c) 2006 - 2019, 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.
+
+**/
+
+#include <IndustryStandard/Mbr.h>
+#include "FatLitePeim.h"
+
+/**
+ Test to see if the Mbr buffer is a valid MBR
+
+ @param[in] Mbr Parent Handle
+ @param[in] LastLba Last Lba address on the device.
+
+ @retval TRUE Mbr is a Valid MBR
+ @retval FALSE Mbr is not a Valid MBR
+
+**/
+BOOLEAN
+PartitionValidMbr (
+ IN MASTER_BOOT_RECORD *Mbr,
+ IN EFI_PEI_LBA LastLba
+ )
+{
+ UINT32 StartingLBA;
+ UINT32 EndingLBA;
+ UINT32 NewEndingLBA;
+ INTN Index1;
+ INTN Index2;
+ BOOLEAN MbrValid;
+
+ if (Mbr->Signature != MBR_SIGNATURE) {
+ return FALSE;
+ }
+ //
+ // The BPB also has this signature, so it can not be used alone.
+ //
+ MbrValid = FALSE;
+ for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {
+ if (Mbr->Partition[Index1].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0) {
+ continue;
+ }
+
+ MbrValid = TRUE;
+ StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);
+ EndingLBA = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;
+ if (EndingLBA > LastLba) {
+ //
+ // Compatability Errata:
+ // Some systems try to hide drive space with thier INT 13h driver
+ // This does not hide space from the OS driver. This means the MBR
+ // that gets created from DOS is smaller than the MBR created from
+ // a real OS (NT & Win98). This leads to BlockIo->LastBlock being
+ // wrong on some systems FDISKed by the OS.
+ //
+ // return FALSE Because no block devices on a system are implemented
+ // with INT 13h
+ //
+ return FALSE;
+ }
+
+ for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {
+ if (Mbr->Partition[Index2].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index2].SizeInLBA) == 0) {
+ continue;
+ }
+
+ NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;
+ if (NewEndingLBA >= StartingLBA && UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA) {
+ //
+ // This region overlaps with the Index1'th region
+ //
+ return FALSE;
+ }
+ }
+ }
+ //
+ // Non of the regions overlapped so MBR is O.K.
+ //
+ return MbrValid;
+}
+
+/**
+ This function finds Mbr partitions. Main algorithm
+ is ported from DXE partition driver.
+
+ @param[in] PrivateData The global memory map
+ @param[in] ParentBlockDevNo The parent block device
+
+ @retval TRUE New partitions are detected and logical block devices
+ are added to block device array
+ @retval FALSE No new partitions are added
+
+**/
+BOOLEAN
+FatFindMbrPartitions (
+ IN PEI_FAT_PRIVATE_DATA *PrivateData,
+ IN UINTN ParentBlockDevNo
+ )
+{
+ EFI_STATUS Status;
+ MASTER_BOOT_RECORD *Mbr;
+ UINTN Index;
+ BOOLEAN Found;
+ PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
+ PEI_FAT_BLOCK_DEVICE *BlockDev;
+
+ if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
+ return FALSE;
+ }
+
+ ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
+
+ if (ParentBlockDev->BlockSize > PEI_FAT_MAX_BLOCK_SIZE) {
+ DEBUG((DEBUG_ERROR, "Device BlockSize %x exceeds FAT_MAX_BLOCK_SIZE\n", ParentBlockDev->BlockSize));
+ return FALSE;
+ }
+
+ Found = FALSE;
+ Mbr = (MASTER_BOOT_RECORD *) PrivateData->BlockData;
+
+ Status = FatReadBlock (
+ PrivateData,
+ ParentBlockDevNo,
+ 0,
+ ParentBlockDev->BlockSize,
+ Mbr
+ );
+
+ if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, ParentBlockDev->LastBlock)) {
+ goto Done;
+ }
+ //
+ // We have a valid mbr - add each partition
+ //
+ for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
+ if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) == 0) {
+ //
+ // Don't use null MBR entries
+ //
+ continue;
+ }
+ //
+ // Register this partition
+ //
+ if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {
+
+ Found = TRUE;
+
+ BlockDev = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);
+
+ BlockDev->BlockSize = MBR_SIZE;
+ BlockDev->LastBlock = UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) - 1;
+ BlockDev->IoAlign = ParentBlockDev->IoAlign;
+ BlockDev->Logical = TRUE;
+ BlockDev->PartitionChecked = FALSE;
+ BlockDev->StartingPos = MultU64x32 (
+ UNPACK_INT32 (Mbr->Partition[Index].StartingLBA),
+ ParentBlockDev->BlockSize
+ );
+ BlockDev->ParentDevNo = ParentBlockDevNo;
+
+ PrivateData->BlockDeviceCount++;
+ }
+ }
+
+Done:
+
+ ParentBlockDev->PartitionChecked = TRUE;
+ return Found;
+}
diff --git a/FatPkg/FatPei/Part.c b/FatPkg/FatPei/Part.c
index be185460f3..8a54e56f5a 100644
--- a/FatPkg/FatPei/Part.c
+++ b/FatPkg/FatPei/Part.c
@@ -2,7 +2,7 @@
Routines supporting partition discovery and
logical device reading
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2019, 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
@@ -14,20 +14,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
-#include <IndustryStandard/Mbr.h>
-#include <IndustryStandard/ElTorito.h>
#include "FatLitePeim.h"
/**
This function finds Eltorito partitions. Main algorithm
is ported from DXE partition driver.
- @param PrivateData The global memory map
- @param ParentBlockDevNo The parent block device
+ @param[in] PrivateData The global memory map
+ @param[in] ParentBlockDevNo The parent block device
@retval TRUE New partitions are detected and logical block devices
- are added to block device array
- @retval FALSE No New partitions are added;
+ are added to block device array
+ @retval FALSE No new partitions are added
**/
BOOLEAN
@@ -40,12 +38,12 @@ FatFindEltoritoPartitions (
This function finds Mbr partitions. Main algorithm
is ported from DXE partition driver.
- @param PrivateData The global memory map
- @param ParentBlockDevNo The parent block device
+ @param[in] PrivateData The global memory map
+ @param[in] ParentBlockDevNo The parent block device
@retval TRUE New partitions are detected and logical block devices
- are added to block device array
- @retval FALSE No New partitions are added;
+ are added to block device array
+ @retval FALSE No new partitions are added
**/
BOOLEAN
@@ -54,7 +52,6 @@ FatFindMbrPartitions (
IN UINTN ParentBlockDevNo
);
-
/**
This function finds partitions (logical devices) in physical block devices.
@@ -83,384 +80,3 @@ FatFindPartitions (
} while (Found && PrivateData->BlockDeviceCount <= PEI_FAT_MAX_BLOCK_DEVICE);
}
-
-/**
- This function finds Eltorito partitions. Main algorithm
- is ported from DXE partition driver.
-
- @param PrivateData The global memory map
- @param ParentBlockDevNo The parent block device
-
- @retval TRUE New partitions are detected and logical block devices
- are added to block device array
- @retval FALSE No New partitions are added;
-
-**/
-BOOLEAN
-FatFindEltoritoPartitions (
- IN PEI_FAT_PRIVATE_DATA *PrivateData,
- IN UINTN ParentBlockDevNo
- )
-{
- EFI_STATUS Status;
- BOOLEAN Found;
- PEI_FAT_BLOCK_DEVICE *BlockDev;
- PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
- UINT32 VolDescriptorLba;
- UINT32 Lba;
- CDROM_VOLUME_DESCRIPTOR *VolDescriptor;
- ELTORITO_CATALOG *Catalog;
- UINTN Check;
- UINTN Index;
- UINTN MaxIndex;
- UINT16 *CheckBuffer;
- UINT32 SubBlockSize;
- UINT32 SectorCount;
- UINT32 VolSpaceSize;
-
- if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
- return FALSE;
- }
-
- Found = FALSE;
- ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
- VolSpaceSize = 0;
-
- //
- // CD_ROM has the fixed block size as 2048 bytes
- //
- if (ParentBlockDev->BlockSize != 2048) {
- return FALSE;
- }
-
- VolDescriptor = (CDROM_VOLUME_DESCRIPTOR *) PrivateData->BlockData;
- Catalog = (ELTORITO_CATALOG *) VolDescriptor;
-
- //
- // the ISO-9660 volume descriptor starts at 32k on the media
- // and CD_ROM has the fixed block size as 2048 bytes, so...
- //
- VolDescriptorLba = 15;
- //
- // ((16*2048) / Media->BlockSize) - 1;
- //
- // Loop: handle one volume descriptor per time
- //
- while (TRUE) {
-
- VolDescriptorLba += 1;
- if (VolDescriptorLba > ParentBlockDev->LastBlock) {
- //
- // We are pointing past the end of the device so exit
- //
- break;
- }
-
- Status = FatReadBlock (
- PrivateData,
- ParentBlockDevNo,
- VolDescriptorLba,
- ParentBlockDev->BlockSize,
- VolDescriptor
- );
- if (EFI_ERROR (Status)) {
- break;
- }
- //
- // Check for valid volume descriptor signature
- //
- if (VolDescriptor->Unknown.Type == CDVOL_TYPE_END ||
- CompareMem (VolDescriptor->Unknown.Id, CDVOL_ID, sizeof (VolDescriptor->Unknown.Id)) != 0
- ) {
- //
- // end of Volume descriptor list
- //
- break;
- }
- //
- // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte
- //
- if (VolDescriptor->Unknown.Type == CDVOL_TYPE_CODED) {
- VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[1];
- }
- //
- // Is it an El Torito volume descriptor?
- //
- if (CompareMem (
- VolDescriptor->BootRecordVolume.SystemId,
- CDVOL_ELTORITO_ID,
- sizeof (CDVOL_ELTORITO_ID) - 1
- ) != 0) {
- continue;
- }
- //
- // Read in the boot El Torito boot catalog
- //
- Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);
- if (Lba > ParentBlockDev->LastBlock) {
- continue;
- }
-
- Status = FatReadBlock (
- PrivateData,
- ParentBlockDevNo,
- Lba,
- ParentBlockDev->BlockSize,
- Catalog
- );
- if (EFI_ERROR (Status)) {
- continue;
- }
- //
- // We don't care too much about the Catalog header's contents, but we do want
- // to make sure it looks like a Catalog header
- //
- if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {
- continue;
- }
-
- Check = 0;
- CheckBuffer = (UINT16 *) Catalog;
- for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {
- Check += CheckBuffer[Index];
- }
-
- if ((Check & 0xFFFF) != 0) {
- continue;
- }
-
- MaxIndex = ParentBlockDev->BlockSize / sizeof (ELTORITO_CATALOG);
- for (Index = 1; Index < MaxIndex; Index += 1) {
- //
- // Next entry
- //
- Catalog += 1;
-
- //
- // Check this entry
- //
- if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {
- continue;
- }
-
- SubBlockSize = 512;
- SectorCount = Catalog->Boot.SectorCount;
-
- switch (Catalog->Boot.MediaType) {
-
- case ELTORITO_NO_EMULATION:
- SubBlockSize = ParentBlockDev->BlockSize;
- SectorCount = Catalog->Boot.SectorCount;
- break;
-
- case ELTORITO_HARD_DISK:
- break;
-
- case ELTORITO_12_DISKETTE:
- SectorCount = 0x50 * 0x02 * 0x0F;
- break;
-
- case ELTORITO_14_DISKETTE:
- SectorCount = 0x50 * 0x02 * 0x12;
- break;
-
- case ELTORITO_28_DISKETTE:
- SectorCount = 0x50 * 0x02 * 0x24;
- break;
-
- default:
- SectorCount = 0;
- SubBlockSize = ParentBlockDev->BlockSize;
- break;
- }
-
- if (SectorCount < 2) {
- SectorCount = (VolSpaceSize > ParentBlockDev->LastBlock + 1) ? (UINT32) (ParentBlockDev->LastBlock - Catalog->Boot.Lba + 1) : (UINT32) (VolSpaceSize - Catalog->Boot.Lba);
- }
- //
- // Register this partition
- //
- if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {
-
- Found = TRUE;
-
- BlockDev = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);
-
- BlockDev->BlockSize = SubBlockSize;
- BlockDev->LastBlock = SectorCount - 1;
- BlockDev->IoAlign = ParentBlockDev->IoAlign;
- BlockDev->Logical = TRUE;
- BlockDev->PartitionChecked = FALSE;
- BlockDev->StartingPos = MultU64x32 (Catalog->Boot.Lba, ParentBlockDev->BlockSize);
- BlockDev->ParentDevNo = ParentBlockDevNo;
-
- PrivateData->BlockDeviceCount++;
- }
- }
- }
-
- ParentBlockDev->PartitionChecked = TRUE;
-
- return Found;
-
-}
-
-
-/**
- Test to see if the Mbr buffer is a valid MBR
-
- @param Mbr Parent Handle
- @param LastLba Last Lba address on the device.
-
- @retval TRUE Mbr is a Valid MBR
- @retval FALSE Mbr is not a Valid MBR
-
-**/
-BOOLEAN
-PartitionValidMbr (
- IN MASTER_BOOT_RECORD *Mbr,
- IN EFI_PEI_LBA LastLba
- )
-{
- UINT32 StartingLBA;
- UINT32 EndingLBA;
- UINT32 NewEndingLBA;
- INTN Index1;
- INTN Index2;
- BOOLEAN MbrValid;
-
- if (Mbr->Signature != MBR_SIGNATURE) {
- return FALSE;
- }
- //
- // The BPB also has this signature, so it can not be used alone.
- //
- MbrValid = FALSE;
- for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {
- if (Mbr->Partition[Index1].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0) {
- continue;
- }
-
- MbrValid = TRUE;
- StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);
- EndingLBA = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;
- if (EndingLBA > LastLba) {
- //
- // Compatability Errata:
- // Some systems try to hide drive space with thier INT 13h driver
- // This does not hide space from the OS driver. This means the MBR
- // that gets created from DOS is smaller than the MBR created from
- // a real OS (NT & Win98). This leads to BlockIo->LastBlock being
- // wrong on some systems FDISKed by the OS.
- //
- // return FALSE Because no block devices on a system are implemented
- // with INT 13h
- //
- return FALSE;
- }
-
- for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {
- if (Mbr->Partition[Index2].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index2].SizeInLBA) == 0) {
- continue;
- }
-
- NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;
- if (NewEndingLBA >= StartingLBA && UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA) {
- //
- // This region overlaps with the Index1'th region
- //
- return FALSE;
- }
- }
- }
- //
- // Non of the regions overlapped so MBR is O.K.
- //
- return MbrValid;
-}
-
-
-/**
- This function finds Mbr partitions. Main algorithm
- is ported from DXE partition driver.
-
- @param PrivateData The global memory map
- @param ParentBlockDevNo The parent block device
-
- @retval TRUE New partitions are detected and logical block devices
- are added to block device array
- @retval FALSE No New partitions are added;
-
-**/
-BOOLEAN
-FatFindMbrPartitions (
- IN PEI_FAT_PRIVATE_DATA *PrivateData,
- IN UINTN ParentBlockDevNo
- )
-{
- EFI_STATUS Status;
- MASTER_BOOT_RECORD *Mbr;
- UINTN Index;
- BOOLEAN Found;
- PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
- PEI_FAT_BLOCK_DEVICE *BlockDev;
-
- if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
- return FALSE;
- }
-
- ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
-
- Found = FALSE;
- Mbr = (MASTER_BOOT_RECORD *) PrivateData->BlockData;
-
- Status = FatReadBlock (
- PrivateData,
- ParentBlockDevNo,
- 0,
- ParentBlockDev->BlockSize,
- Mbr
- );
-
- if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, ParentBlockDev->LastBlock)) {
- goto Done;
- }
- //
- // We have a valid mbr - add each partition
- //
- for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
- if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) == 0) {
- //
- // Don't use null MBR entries
- //
- continue;
- }
- //
- // Register this partition
- //
- if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {
-
- Found = TRUE;
-
- BlockDev = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);
-
- BlockDev->BlockSize = MBR_SIZE;
- BlockDev->LastBlock = UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) - 1;
- BlockDev->IoAlign = ParentBlockDev->IoAlign;
- BlockDev->Logical = TRUE;
- BlockDev->PartitionChecked = FALSE;
- BlockDev->StartingPos = MultU64x32 (
- UNPACK_INT32 (Mbr->Partition[Index].StartingLBA),
- ParentBlockDev->BlockSize
- );
- BlockDev->ParentDevNo = ParentBlockDevNo;
-
- PrivateData->BlockDeviceCount++;
- }
- }
-
-Done:
-
- ParentBlockDev->PartitionChecked = TRUE;
- return Found;
-}
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 2/3] MdePkg/UefiGpt.h: Add new definition for enable GPT support
2019-01-29 5:27 [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3 Chen A Chen
2019-01-29 5:27 ` [PATCH v3 1/3] FatPkg: Break down Part.c file Chen A Chen
@ 2019-01-29 5:27 ` Chen A Chen
2019-01-29 5:27 ` [PATCH v3 3/3] FatPkg: Add GPT check in FatPei to support Capsule-on-Disk feature Chen A Chen
2019-01-31 3:13 ` [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3 Wu, Hao A
3 siblings, 0 replies; 6+ messages in thread
From: Chen A Chen @ 2019-01-29 5:27 UTC (permalink / raw)
To: edk2-devel; +Cc: Chen A Chen, Liming Gao, Michael D Kinney, Zhang Chao B
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1470
This definition comes from UEFI Spec to support GPT in FatPei driver.
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Zhang Chao B <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
---
MdePkg/Include/Uefi/UefiGpt.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/MdePkg/Include/Uefi/UefiGpt.h b/MdePkg/Include/Uefi/UefiGpt.h
index f635b05390..e4e919beaf 100644
--- a/MdePkg/Include/Uefi/UefiGpt.h
+++ b/MdePkg/Include/Uefi/UefiGpt.h
@@ -1,7 +1,7 @@
/** @file
EFI Guid Partition Table Format Definition.
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2019, 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 that accompanies this distribution.
The full text of the license may be found at
@@ -24,6 +24,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
/// EFI Partition Table Signature: "EFI PART".
///
#define EFI_PTAB_HEADER_ID SIGNATURE_64 ('E','F','I',' ','P','A','R','T')
+///
+/// Minimum bytes reserve for EFI entry array buffer.
+///
+#define EFI_GPT_PART_ENTRY_MIN_SIZE 16384
#pragma pack(1)
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 3/3] FatPkg: Add GPT check in FatPei to support Capsule-on-Disk feature.
2019-01-29 5:27 [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3 Chen A Chen
2019-01-29 5:27 ` [PATCH v3 1/3] FatPkg: Break down Part.c file Chen A Chen
2019-01-29 5:27 ` [PATCH v3 2/3] MdePkg/UefiGpt.h: Add new definition for enable GPT support Chen A Chen
@ 2019-01-29 5:27 ` Chen A Chen
2019-01-30 8:37 ` Wu, Hao A
2019-01-31 3:13 ` [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3 Wu, Hao A
3 siblings, 1 reply; 6+ messages in thread
From: Chen A Chen @ 2019-01-29 5:27 UTC (permalink / raw)
To: edk2-devel; +Cc: Chen A Chen, Ruiyu Ni, Zhang Chao B
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1470
This feature is used for finding GPT partition.
Follow the following step to check.
1) Check Protective MBR.
2) Check GPT primary/backup header.
3) Check GPT primary/backup entry array.
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Zhang Chao B <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
---
FatPkg/FatPei/FatLitePeim.h | 3 +-
FatPkg/FatPei/FatPei.inf | 3 +
FatPkg/FatPei/Gpt.c | 548 ++++++++++++++++++++++++++++++++++++++++++++
FatPkg/FatPei/Part.c | 36 ++-
4 files changed, 585 insertions(+), 5 deletions(-)
create mode 100644 FatPkg/FatPei/Gpt.c
diff --git a/FatPkg/FatPei/FatLitePeim.h b/FatPkg/FatPei/FatLitePeim.h
index fbf887da5f..82ab045f2a 100644
--- a/FatPkg/FatPei/FatLitePeim.h
+++ b/FatPkg/FatPei/FatLitePeim.h
@@ -1,7 +1,7 @@
/** @file
Data structures for FAT recovery PEIM
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2019, 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
@@ -27,6 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/BaseLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/PeiServicesLib.h>
diff --git a/FatPkg/FatPei/FatPei.inf b/FatPkg/FatPei/FatPei.inf
index 57312a9047..050bc4e157 100644
--- a/FatPkg/FatPei/FatPei.inf
+++ b/FatPkg/FatPei/FatPei.inf
@@ -31,6 +31,7 @@
[Sources]
Mbr.c
+ Gpt.c
Eltorito.c
Part.c
FatLiteApi.c
@@ -49,6 +50,7 @@
[LibraryClasses]
PcdLib
BaseMemoryLib
+ MemoryAllocationLib
PeimEntryPoint
BaseLib
DebugLib
@@ -61,6 +63,7 @@
gRecoveryOnFatIdeDiskGuid ## SOMETIMES_CONSUMES ## UNDEFINED
gRecoveryOnFatFloppyDiskGuid ## SOMETIMES_CONSUMES ## UNDEFINED
gRecoveryOnFatNvmeDiskGuid ## SOMETIMES_CONSUMES ## UNDEFINED
+ gEfiPartTypeUnusedGuid ## SOMETIMES_CONSUMES ## UNDEFINED
[Ppis]
diff --git a/FatPkg/FatPei/Gpt.c b/FatPkg/FatPei/Gpt.c
new file mode 100644
index 0000000000..c3afb668d7
--- /dev/null
+++ b/FatPkg/FatPei/Gpt.c
@@ -0,0 +1,548 @@
+/** @file
+ Routines supporting partition discovery and
+ logical device reading
+
+Copyright (c) 2019 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.
+
+**/
+
+#include <IndustryStandard/Mbr.h>
+#include <Uefi/UefiGpt.h>
+#include <Library/BaseLib.h>
+#include "FatLitePeim.h"
+
+//
+// Assumption: 'a' and 'blocksize' are all UINT32 or UINT64.
+// If 'a' and 'blocksize' are not the same type, should use DivU64xU32 to calculate.
+//
+#define EFI_SIZE_TO_BLOCKS(a, blocksize) (((a) / (blocksize)) + (((a) % (blocksize)) ? 1 : 0))
+
+//
+// GPT Partition Entry Status
+//
+typedef struct {
+ BOOLEAN OutOfRange;
+ BOOLEAN Overlap;
+ BOOLEAN OsSpecific;
+} EFI_PARTITION_ENTRY_STATUS;
+
+/**
+ Check if the CRC field in the Partition table header is valid.
+
+ @param[in] PartHeader Partition table header structure
+
+ @retval TRUE the CRC is valid
+ @retval FALSE the CRC is invalid
+
+**/
+BOOLEAN
+PartitionCheckGptHeaderCRC (
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader
+ )
+{
+ UINT32 GptHdrCrc;
+ UINT32 Crc;
+
+ GptHdrCrc = PartHeader->Header.CRC32;
+
+ //
+ // Set CRC field to zero when doing calcuation
+ //
+ PartHeader->Header.CRC32 = 0;
+
+ Crc = CalculateCrc32 (PartHeader, PartHeader->Header.HeaderSize);
+
+ //
+ // Restore Header CRC
+ //
+ PartHeader->Header.CRC32 = GptHdrCrc;
+
+ return (GptHdrCrc == Crc);
+}
+
+
+/**
+ Check if the CRC field in the Partition table header is valid
+ for Partition entry array.
+
+ @param[in] PartHeader Partition table header structure
+ @param[in] PartEntry The partition entry array
+
+ @retval TRUE the CRC is valid
+ @retval FALSE the CRC is invalid
+
+**/
+BOOLEAN
+PartitionCheckGptEntryArrayCRC (
+ IN EFI_PARTITION_TABLE_HEADER *PartHeader,
+ IN EFI_PARTITION_ENTRY *PartEntry
+ )
+{
+ UINT32 Crc;
+ UINTN Size;
+
+ Size = (UINTN)MultU64x32(PartHeader->NumberOfPartitionEntries, PartHeader->SizeOfPartitionEntry);
+ Crc = CalculateCrc32 (PartEntry, Size);
+
+ return (BOOLEAN) (PartHeader->PartitionEntryArrayCRC32 == Crc);
+}
+
+/**
+ The function is used for valid GPT table. Both for Primary and Backup GPT header.
+
+ @param[in] PrivateData The global memory map
+ @param[in] ParentBlockDevNo The parent block device
+ @param[in] IsPrimaryHeader Indicate to which header will be checked.
+ @param[in] PartHdr Stores the partition table that is read
+
+ @retval TRUE The partition table is valid
+ @retval FALSE The partition table is not valid
+
+**/
+BOOLEAN
+PartitionCheckGptHeader (
+ IN PEI_FAT_PRIVATE_DATA *PrivateData,
+ IN UINTN ParentBlockDevNo,
+ IN BOOLEAN IsPrimaryHeader,
+ IN EFI_PARTITION_TABLE_HEADER *PartHdr
+ )
+{
+ PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
+ EFI_PEI_LBA Lba;
+ EFI_PEI_LBA AlternateLba;
+ EFI_PEI_LBA EntryArrayLastLba;
+
+ UINT64 PartitionEntryArraySize;
+ UINT64 PartitionEntryBlockNumb;
+ UINT32 EntryArraySizeRemainder;
+
+ ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
+
+ if (IsPrimaryHeader) {
+ Lba = PRIMARY_PART_HEADER_LBA;
+ AlternateLba = ParentBlockDev->LastBlock;
+ } else {
+ Lba = ParentBlockDev->LastBlock;
+ AlternateLba = PRIMARY_PART_HEADER_LBA;
+ }
+
+ if ( (PartHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
+ (PartHdr->Header.Revision != 0x00010000) ||
+ (PartHdr->Header.HeaderSize < 92) ||
+ (PartHdr->Header.HeaderSize > ParentBlockDev->BlockSize) ||
+ (!PartitionCheckGptHeaderCRC (PartHdr)) ||
+ (PartHdr->Header.Reserved != 0)
+ ) {
+ DEBUG ((DEBUG_ERROR, "Invalid efi partition table header\n"));
+ return FALSE;
+ }
+
+ //
+ // | Block0 | Block1 |Block2 ~ FirstUsableLBA - 1|FirstUsableLBA, ... ,LastUsableLBA|LastUsableLBA+1 ~ LastBlock-1| LastBlock |
+ // |Protective MBR|Primary Header|Entry Array(At Least 16384)| Partition | Entry Array(At Least 16384) |BackUp Header|
+ //
+ // 1. Protective MBR is fixed at Block 0.
+ // 2. Primary Header is fixed at Block 1.
+ // 3. Backup Header is fixed at LastBlock.
+ // 4. Must be remain 128*128 bytes for primary entry array.
+ // 5. Must be remain 128*128 bytes for backup entry array.
+ // 6. SizeOfPartitionEntry must be equals to 128 * 2^n.
+ //
+ if ( (PartHdr->MyLBA != Lba) ||
+ (PartHdr->AlternateLBA != AlternateLba) ||
+ (PartHdr->FirstUsableLBA < 2 + EFI_SIZE_TO_BLOCKS (EFI_GPT_PART_ENTRY_MIN_SIZE, ParentBlockDev->BlockSize)) ||
+ (PartHdr->LastUsableLBA > ParentBlockDev->LastBlock - 1 - EFI_SIZE_TO_BLOCKS (EFI_GPT_PART_ENTRY_MIN_SIZE, ParentBlockDev->BlockSize)) ||
+ (PartHdr->FirstUsableLBA > PartHdr->LastUsableLBA) ||
+ (PartHdr->PartitionEntryLBA < 2) ||
+ (PartHdr->PartitionEntryLBA > ParentBlockDev->LastBlock - 1) ||
+ (PartHdr->PartitionEntryLBA >= PartHdr->FirstUsableLBA && PartHdr->PartitionEntryLBA <= PartHdr->LastUsableLBA) ||
+ (PartHdr->SizeOfPartitionEntry%128 != 0) ||
+ (PartHdr->SizeOfPartitionEntry != sizeof (EFI_PARTITION_ENTRY))
+ ) {
+ DEBUG ((DEBUG_ERROR, "Invalid efi partition table header\n"));
+ return FALSE;
+ }
+
+ //
+ // Ensure the NumberOfPartitionEntries * SizeOfPartitionEntry doesn't overflow.
+ //
+ if (PartHdr->NumberOfPartitionEntries > DivU64x32 (MAX_UINTN, PartHdr->SizeOfPartitionEntry)) {
+ DEBUG ((DEBUG_ERROR, "Memory overflow in GPT Entry Array\n"));
+ return FALSE;
+ }
+
+ PartitionEntryArraySize = MultU64x32 (PartHdr->NumberOfPartitionEntries, PartHdr->SizeOfPartitionEntry);
+ EntryArraySizeRemainder = 0;
+ PartitionEntryBlockNumb = DivU64x32Remainder (PartitionEntryArraySize, ParentBlockDev->BlockSize, &EntryArraySizeRemainder);
+ if (EntryArraySizeRemainder != 0) {
+ PartitionEntryBlockNumb++;
+ }
+
+ if (IsPrimaryHeader) {
+ EntryArrayLastLba = PartHdr->FirstUsableLBA;
+ } else {
+ EntryArrayLastLba = ParentBlockDev->LastBlock;
+ }
+
+ //
+ // Make sure partition entry array not overlaps with partition area or the LastBlock.
+ //
+ if (PartHdr->PartitionEntryLBA + PartitionEntryBlockNumb > EntryArrayLastLba) {
+ DEBUG ((DEBUG_ERROR, "GPT Partition Entry Array Error!\n"));
+ DEBUG ((DEBUG_ERROR, "PartitionEntryArraySize = %lu.\n", PartitionEntryArraySize));
+ DEBUG ((DEBUG_ERROR, "PartitionEntryLBA = %lu.\n", PartHdr->PartitionEntryLBA));
+ DEBUG ((DEBUG_ERROR, "PartitionEntryBlockNumb = %lu.\n", PartitionEntryBlockNumb));
+ DEBUG ((DEBUG_ERROR, "EntryArrayLastLba = %lu.\n", EntryArrayLastLba));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ This function is used to verify each partition in block device.
+
+ @param[in] PrivateData The global memory map
+ @param[in] ParentBlockDevNo The parent block device
+ @param[in] PartHdr Stores the partition table that is read
+
+ @retval TRUE The partition is valid
+ @retval FALSE The partition is not valid
+
+**/
+BOOLEAN
+PartitionCheckGptEntryArray (
+ IN PEI_FAT_PRIVATE_DATA *PrivateData,
+ IN UINTN ParentBlockDevNo,
+ IN EFI_PARTITION_TABLE_HEADER *PartHdr
+ )
+{
+ EFI_STATUS Status;
+ PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
+ PEI_FAT_BLOCK_DEVICE *BlockDevPtr;
+
+ UINT64 PartitionEntryArraySize;
+ UINT64 PartitionEntryBlockNumb;
+ UINT32 EntryArraySizeRemainder;
+
+ EFI_PARTITION_ENTRY *PartitionEntryBuffer;
+ EFI_PARTITION_ENTRY_STATUS *PartitionEntryStatus;
+
+ BOOLEAN Found;
+ EFI_LBA StartingLBA;
+ EFI_LBA EndingLBA;
+ UINTN Index;
+ UINTN Index1;
+ UINTN Index2;
+ EFI_PARTITION_ENTRY *Entry;
+
+ ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
+ Found = FALSE;
+
+ PartitionEntryArraySize = MultU64x32 (PartHdr->NumberOfPartitionEntries, PartHdr->SizeOfPartitionEntry);
+ EntryArraySizeRemainder = 0;
+ PartitionEntryBlockNumb = DivU64x32Remainder (PartitionEntryArraySize, ParentBlockDev->BlockSize, &EntryArraySizeRemainder);
+ if (EntryArraySizeRemainder != 0) {
+ PartitionEntryBlockNumb++;
+ }
+ PartitionEntryArraySize = MultU64x32 (PartitionEntryBlockNumb, ParentBlockDev->BlockSize);
+
+ PartitionEntryBuffer = (EFI_PARTITION_ENTRY *) AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)PartitionEntryArraySize));
+ if (PartitionEntryBuffer == NULL) {
+ DEBUG ((DEBUG_ERROR, "Allocate memory error!\n"));
+ goto EXIT;
+ }
+
+ PartitionEntryStatus = (EFI_PARTITION_ENTRY_STATUS *) AllocatePages (EFI_SIZE_TO_PAGES (PartHdr->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS)));
+ if (PartitionEntryStatus == NULL) {
+ DEBUG ((DEBUG_ERROR, "Allocate memory error!\n"));
+ goto EXIT;
+ }
+ ZeroMem (PartitionEntryStatus, PartHdr->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS));
+
+ Status = FatReadBlock (
+ PrivateData,
+ ParentBlockDevNo,
+ PartHdr->PartitionEntryLBA,
+ (UINTN)PartitionEntryArraySize,
+ PartitionEntryBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Read partition entry array error!\n"));
+ goto EXIT;
+ }
+
+ if (!PartitionCheckGptEntryArrayCRC (PartHdr, PartitionEntryBuffer)) {
+ DEBUG ((DEBUG_ERROR, "Partition entries CRC check fail\n"));
+ goto EXIT;
+ }
+
+ for (Index1 = 0; Index1 < PartHdr->NumberOfPartitionEntries; Index1++) {
+ Entry = (EFI_PARTITION_ENTRY *) ((UINT8 *) PartitionEntryBuffer + Index1 * PartHdr->SizeOfPartitionEntry);
+ if (CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
+ continue;
+ }
+
+ StartingLBA = Entry->StartingLBA;
+ EndingLBA = Entry->EndingLBA;
+ if (StartingLBA > EndingLBA ||
+ StartingLBA < PartHdr->FirstUsableLBA ||
+ StartingLBA > PartHdr->LastUsableLBA ||
+ EndingLBA < PartHdr->FirstUsableLBA ||
+ EndingLBA > PartHdr->LastUsableLBA
+ ) {
+ PartitionEntryStatus[Index1].OutOfRange = TRUE;
+ continue;
+ }
+
+ if ((Entry->Attributes & BIT1) != 0) {
+ //
+ // If Bit 1 is set, this indicate that this is an OS specific GUID partition.
+ //
+ PartitionEntryStatus[Index1].OsSpecific = TRUE;
+ }
+
+ for (Index2 = Index1 + 1; Index2 < PartHdr->NumberOfPartitionEntries; Index2++) {
+ Entry = (EFI_PARTITION_ENTRY *) ((UINT8 *) PartitionEntryBuffer + Index2 * PartHdr->SizeOfPartitionEntry);
+ if (CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
+ continue;
+ }
+
+ if (Entry->EndingLBA >= StartingLBA && Entry->StartingLBA <= EndingLBA) {
+ //
+ // This region overlaps with the Index1'th region
+ //
+ PartitionEntryStatus[Index1].Overlap = TRUE;
+ PartitionEntryStatus[Index2].Overlap = TRUE;
+ continue;
+ }
+ }
+ }
+
+ for (Index = 0; Index < PartHdr->NumberOfPartitionEntries; Index++) {
+ if (CompareGuid (&PartitionEntryBuffer[Index].PartitionTypeGUID, &gEfiPartTypeUnusedGuid)||
+ PartitionEntryStatus[Index].OutOfRange ||
+ PartitionEntryStatus[Index].Overlap ||
+ PartitionEntryStatus[Index].OsSpecific) {
+ //
+ // Don't use null EFI Partition Entries, Invalid Partition Entries or OS specific
+ // partition Entries
+ //
+ continue;
+ }
+
+ if (PrivateData->BlockDeviceCount >= PEI_FAT_MAX_BLOCK_DEVICE) {
+ break;
+ }
+
+ Found = TRUE;
+ BlockDevPtr = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);
+
+ BlockDevPtr->BlockSize = ParentBlockDev->BlockSize;
+ BlockDevPtr->LastBlock = PartitionEntryBuffer[Index].EndingLBA;
+ BlockDevPtr->IoAlign = ParentBlockDev->IoAlign;
+ BlockDevPtr->Logical = TRUE;
+ BlockDevPtr->PartitionChecked = FALSE;
+ BlockDevPtr->StartingPos = MultU64x32 (
+ PartitionEntryBuffer[Index].StartingLBA,
+ ParentBlockDev->BlockSize
+ );
+ BlockDevPtr->ParentDevNo = ParentBlockDevNo;
+
+ PrivateData->BlockDeviceCount++;
+
+ DEBUG ((DEBUG_INFO, "Find GPT Partition [0x%lx", PartitionEntryBuffer[Index].StartingLBA, BlockDevPtr->LastBlock));
+ DEBUG ((DEBUG_INFO, ", 0x%lx]\n", BlockDevPtr->LastBlock));
+ DEBUG ((DEBUG_INFO, " BlockSize %x\n", BlockDevPtr->BlockSize));
+ }
+
+EXIT:
+ if (PartitionEntryBuffer != NULL) {
+ FreePages (PartitionEntryBuffer, EFI_SIZE_TO_PAGES ((UINTN)PartitionEntryArraySize));
+ }
+
+ if (PartitionEntryStatus != NULL) {
+ FreePages (PartitionEntryStatus, EFI_SIZE_TO_PAGES (PartHdr->NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS)));
+ }
+
+ return Found;
+}
+
+/**
+ The function is used to check GPT structure, include GPT header and GPT entry array.
+
+ 1. Check GPT header.
+ 2. Check partition entry array.
+ 3. Check each partitions.
+
+ @param[in] PrivateData The global memory map
+ @param[in] ParentBlockDevNo The parent block device
+ @param[in] IsPrimary Indicate primary or backup to be check
+
+ @retval TRUE Primary or backup GPT structure is valid.
+ @retval FALSE Both primary and backup are invalid.
+
+**/
+BOOLEAN
+PartitionCheckGptStructure (
+ IN PEI_FAT_PRIVATE_DATA *PrivateData,
+ IN UINTN ParentBlockDevNo,
+ IN BOOLEAN IsPrimary
+ )
+{
+ EFI_STATUS Status;
+ PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
+ EFI_PARTITION_TABLE_HEADER *PartHdr;
+ EFI_PEI_LBA GptHeaderLBA;
+
+ ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
+ PartHdr = (EFI_PARTITION_TABLE_HEADER *) PrivateData->BlockData;
+
+ if (IsPrimary) {
+ GptHeaderLBA = PRIMARY_PART_HEADER_LBA;
+ } else {
+ GptHeaderLBA = ParentBlockDev->LastBlock;
+ }
+
+ Status = FatReadBlock (
+ PrivateData,
+ ParentBlockDevNo,
+ GptHeaderLBA,
+ ParentBlockDev->BlockSize,
+ PartHdr
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ if (!PartitionCheckGptHeader (PrivateData, ParentBlockDevNo, IsPrimary, PartHdr)) {
+ return FALSE;
+ }
+
+ if (!PartitionCheckGptEntryArray (PrivateData, ParentBlockDevNo, PartHdr)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ This function is used to check protective MBR structure before checking GPT.
+
+ @param[in] PrivateData The global memory map
+ @param[in] ParentBlockDevNo The parent block device
+
+ @retval TRUE Valid protective MBR
+ @retval FALSE Invalid MBR
+**/
+BOOLEAN
+PartitionCheckProtectiveMbr (
+ IN PEI_FAT_PRIVATE_DATA *PrivateData,
+ IN UINTN ParentBlockDevNo
+ )
+{
+ EFI_STATUS Status;
+ MASTER_BOOT_RECORD *ProtectiveMbr;
+ MBR_PARTITION_RECORD *MbrPartition;
+ PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
+ UINTN Index;
+
+ ProtectiveMbr = (MASTER_BOOT_RECORD *) PrivateData->BlockData;
+ ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
+
+ //
+ // Read Protective MBR
+ //
+ Status = FatReadBlock (
+ PrivateData,
+ ParentBlockDevNo,
+ 0,
+ ParentBlockDev->BlockSize,
+ ProtectiveMbr
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "GPT Error When Read Protective Mbr From Partition!\n"));
+ return FALSE;
+ }
+
+ if (ProtectiveMbr->Signature != MBR_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, "Protective Mbr Signature is invalid!\n"));
+ return FALSE;
+ }
+
+ //
+ // The partition define in UEFI Spec Table 17.
+ // Boot Code, Unique MBR Disk Signature, Unknown.
+ // These parts will not be used by UEFI, so we skip to check them.
+ //
+ for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
+ MbrPartition = (MBR_PARTITION_RECORD *)&ProtectiveMbr->Partition[Index];
+ if (MbrPartition->BootIndicator == 0x00 &&
+ MbrPartition->StartSector == 0x02 &&
+ MbrPartition->OSIndicator == PMBR_GPT_PARTITION &&
+ UNPACK_UINT32 (MbrPartition->StartingLBA) == 1
+ ) {
+ return TRUE;
+ }
+ }
+
+ DEBUG ((DEBUG_ERROR, "Protective Mbr, All Partition Entry Are Empty!\n"));
+ return FALSE;
+}
+
+/**
+ This function is used for finding GPT partition on block device.
+ As follow UEFI spec we should check protective MBR first and then
+ try to check both primary/backup GPT structures.
+
+ @param[in] PrivateData The global memory map
+ @param[in] ParentBlockDevNo The parent block device
+
+ @retval TRUE New partitions are detected and logical block devices
+ are added to block device array
+ @retval FALSE No new partitions are added
+
+**/
+BOOLEAN
+FatFindGptPartitions (
+ IN PEI_FAT_PRIVATE_DATA *PrivateData,
+ IN UINTN ParentBlockDevNo
+ )
+{
+ BOOLEAN Found;
+ PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
+
+ if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
+ return FALSE;
+ }
+
+ ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
+ if (ParentBlockDev->BlockSize > PEI_FAT_MAX_BLOCK_SIZE) {
+ DEBUG ((DEBUG_ERROR, "Device BlockSize %x exceed FAT_MAX_BLOCK_SIZE\n", ParentBlockDev->BlockSize));
+ return FALSE;
+ }
+
+ if (!PartitionCheckProtectiveMbr (PrivateData, ParentBlockDevNo)) {
+ return FALSE;
+ }
+
+ Found = PartitionCheckGptStructure (PrivateData, ParentBlockDevNo, TRUE);
+ if (!Found) {
+ DEBUG ((DEBUG_ERROR, "Primary GPT Header Error, Try to Check Backup GPT Header!\n"));
+ Found = PartitionCheckGptStructure (PrivateData, ParentBlockDevNo, FALSE);
+ }
+
+ if (Found) {
+ ParentBlockDev->PartitionChecked = TRUE;
+ }
+
+ return Found;
+}
diff --git a/FatPkg/FatPei/Part.c b/FatPkg/FatPei/Part.c
index 8a54e56f5a..9b49eccf4e 100644
--- a/FatPkg/FatPei/Part.c
+++ b/FatPkg/FatPei/Part.c
@@ -52,6 +52,25 @@ FatFindMbrPartitions (
IN UINTN ParentBlockDevNo
);
+/**
+ This function is used for finding GPT partition on block device.
+ As follow UEFI spec we should check protective MBR first and then
+ try to check both primary/backup GPT structures.
+
+ @param[in] PrivateData The global memory map
+ @param[in] ParentBlockDevNo The parent block device
+
+ @retval TRUE New partitions are detected and logical block devices
+ are added to block device array
+ @retval FALSE No new partitions are added
+
+**/
+BOOLEAN
+FatFindGptPartitions (
+ IN PEI_FAT_PRIVATE_DATA *PrivateData,
+ IN UINTN ParentBlockDevNo
+ );
+
/**
This function finds partitions (logical devices) in physical block devices.
@@ -71,12 +90,21 @@ FatFindPartitions (
for (Index = 0; Index < PrivateData->BlockDeviceCount; Index++) {
if (!PrivateData->BlockDevice[Index].PartitionChecked) {
- Found = FatFindMbrPartitions (PrivateData, Index);
- if (!Found) {
- Found = FatFindEltoritoPartitions (PrivateData, Index);
+ if (FatFindGptPartitions (PrivateData, Index)) {
+ Found = TRUE;
+ continue;
+ }
+
+ if (FatFindMbrPartitions (PrivateData, Index)) {
+ Found = TRUE;
+ continue;
+ }
+
+ if (FatFindEltoritoPartitions (PrivateData, Index)) {
+ Found = TRUE;
+ continue;
}
}
}
} while (Found && PrivateData->BlockDeviceCount <= PEI_FAT_MAX_BLOCK_DEVICE);
}
-
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 3/3] FatPkg: Add GPT check in FatPei to support Capsule-on-Disk feature.
2019-01-29 5:27 ` [PATCH v3 3/3] FatPkg: Add GPT check in FatPei to support Capsule-on-Disk feature Chen A Chen
@ 2019-01-30 8:37 ` Wu, Hao A
0 siblings, 0 replies; 6+ messages in thread
From: Wu, Hao A @ 2019-01-30 8:37 UTC (permalink / raw)
To: Chen, Chen A, edk2-devel@lists.01.org; +Cc: Ni, Ray, Zhang, Chao B
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Chen
> A Chen
> Sent: Tuesday, January 29, 2019 1:28 PM
> To: edk2-devel@lists.01.org
> Cc: Ni, Ray; Zhang, Chao B
> Subject: [edk2] [PATCH v3 3/3] FatPkg: Add GPT check in FatPei to support
> Capsule-on-Disk feature.
>
> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1470
> This feature is used for finding GPT partition.
> Follow the following step to check.
> 1) Check Protective MBR.
> 2) Check GPT primary/backup header.
> 3) Check GPT primary/backup entry array.
>
> Cc: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Zhang Chao B <chao.b.zhang@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Chen A Chen <chen.a.chen@intel.com>
> Reviewed-by: Hao Wu <hao.a.wu@intel.com>
> ---
> FatPkg/FatPei/FatLitePeim.h | 3 +-
> FatPkg/FatPei/FatPei.inf | 3 +
> FatPkg/FatPei/Gpt.c | 548
> ++++++++++++++++++++++++++++++++++++++++++++
> FatPkg/FatPei/Part.c | 36 ++-
> 4 files changed, 585 insertions(+), 5 deletions(-)
> create mode 100644 FatPkg/FatPei/Gpt.c
>
> diff --git a/FatPkg/FatPei/FatLitePeim.h b/FatPkg/FatPei/FatLitePeim.h
> index fbf887da5f..82ab045f2a 100644
> --- a/FatPkg/FatPei/FatLitePeim.h
> +++ b/FatPkg/FatPei/FatLitePeim.h
> @@ -1,7 +1,7 @@
> /** @file
> Data structures for FAT recovery PEIM
>
> -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2006 - 2019, 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
> @@ -27,6 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> KIND, EITHER EXPRESS OR IMPLIED.
> #include <Library/BaseLib.h>
> #include <Library/PeimEntryPoint.h>
> #include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> #include <Library/PcdLib.h>
> #include <Library/PeiServicesTablePointerLib.h>
> #include <Library/PeiServicesLib.h>
> diff --git a/FatPkg/FatPei/FatPei.inf b/FatPkg/FatPei/FatPei.inf
> index 57312a9047..050bc4e157 100644
> --- a/FatPkg/FatPei/FatPei.inf
> +++ b/FatPkg/FatPei/FatPei.inf
> @@ -31,6 +31,7 @@
>
> [Sources]
> Mbr.c
> + Gpt.c
> Eltorito.c
> Part.c
> FatLiteApi.c
> @@ -49,6 +50,7 @@
> [LibraryClasses]
> PcdLib
> BaseMemoryLib
> + MemoryAllocationLib
> PeimEntryPoint
> BaseLib
> DebugLib
> @@ -61,6 +63,7 @@
> gRecoveryOnFatIdeDiskGuid ## SOMETIMES_CONSUMES ##
> UNDEFINED
> gRecoveryOnFatFloppyDiskGuid ## SOMETIMES_CONSUMES ##
> UNDEFINED
> gRecoveryOnFatNvmeDiskGuid ## SOMETIMES_CONSUMES ##
> UNDEFINED
> + gEfiPartTypeUnusedGuid ## SOMETIMES_CONSUMES ##
> UNDEFINED
>
>
> [Ppis]
> diff --git a/FatPkg/FatPei/Gpt.c b/FatPkg/FatPei/Gpt.c
> new file mode 100644
> index 0000000000..c3afb668d7
> --- /dev/null
> +++ b/FatPkg/FatPei/Gpt.c
> @@ -0,0 +1,548 @@
> +/** @file
> + Routines supporting partition discovery and
> + logical device reading
> +
> +Copyright (c) 2019 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.
> +
> +**/
> +
> +#include <IndustryStandard/Mbr.h>
> +#include <Uefi/UefiGpt.h>
> +#include <Library/BaseLib.h>
> +#include "FatLitePeim.h"
> +
> +//
> +// Assumption: 'a' and 'blocksize' are all UINT32 or UINT64.
> +// If 'a' and 'blocksize' are not the same type, should use DivU64xU32 to
> calculate.
> +//
> +#define EFI_SIZE_TO_BLOCKS(a, blocksize) (((a) / (blocksize)) + (((a) %
> (blocksize)) ? 1 : 0))
> +
> +//
> +// GPT Partition Entry Status
> +//
> +typedef struct {
> + BOOLEAN OutOfRange;
> + BOOLEAN Overlap;
> + BOOLEAN OsSpecific;
> +} EFI_PARTITION_ENTRY_STATUS;
> +
> +/**
> + Check if the CRC field in the Partition table header is valid.
> +
> + @param[in] PartHeader Partition table header structure
> +
> + @retval TRUE the CRC is valid
> + @retval FALSE the CRC is invalid
> +
> +**/
> +BOOLEAN
> +PartitionCheckGptHeaderCRC (
> + IN EFI_PARTITION_TABLE_HEADER *PartHeader
> + )
> +{
> + UINT32 GptHdrCrc;
> + UINT32 Crc;
> +
> + GptHdrCrc = PartHeader->Header.CRC32;
> +
> + //
> + // Set CRC field to zero when doing calcuation
> + //
> + PartHeader->Header.CRC32 = 0;
> +
> + Crc = CalculateCrc32 (PartHeader, PartHeader->Header.HeaderSize);
> +
> + //
> + // Restore Header CRC
> + //
> + PartHeader->Header.CRC32 = GptHdrCrc;
> +
> + return (GptHdrCrc == Crc);
> +}
> +
> +
> +/**
> + Check if the CRC field in the Partition table header is valid
> + for Partition entry array.
> +
> + @param[in] PartHeader Partition table header structure
> + @param[in] PartEntry The partition entry array
> +
> + @retval TRUE the CRC is valid
> + @retval FALSE the CRC is invalid
> +
> +**/
> +BOOLEAN
> +PartitionCheckGptEntryArrayCRC (
> + IN EFI_PARTITION_TABLE_HEADER *PartHeader,
> + IN EFI_PARTITION_ENTRY *PartEntry
> + )
> +{
> + UINT32 Crc;
> + UINTN Size;
> +
> + Size = (UINTN)MultU64x32(PartHeader->NumberOfPartitionEntries,
> PartHeader->SizeOfPartitionEntry);
> + Crc = CalculateCrc32 (PartEntry, Size);
> +
> + return (BOOLEAN) (PartHeader->PartitionEntryArrayCRC32 == Crc);
> +}
> +
> +/**
> + The function is used for valid GPT table. Both for Primary and Backup GPT
> header.
> +
> + @param[in] PrivateData The global memory map
> + @param[in] ParentBlockDevNo The parent block device
> + @param[in] IsPrimaryHeader Indicate to which header will be checked.
> + @param[in] PartHdr Stores the partition table that is read
> +
> + @retval TRUE The partition table is valid
> + @retval FALSE The partition table is not valid
> +
> +**/
> +BOOLEAN
> +PartitionCheckGptHeader (
> + IN PEI_FAT_PRIVATE_DATA *PrivateData,
> + IN UINTN ParentBlockDevNo,
> + IN BOOLEAN IsPrimaryHeader,
> + IN EFI_PARTITION_TABLE_HEADER *PartHdr
> + )
> +{
> + PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
> + EFI_PEI_LBA Lba;
> + EFI_PEI_LBA AlternateLba;
> + EFI_PEI_LBA EntryArrayLastLba;
> +
> + UINT64 PartitionEntryArraySize;
> + UINT64 PartitionEntryBlockNumb;
> + UINT32 EntryArraySizeRemainder;
> +
> + ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
> +
> + if (IsPrimaryHeader) {
> + Lba = PRIMARY_PART_HEADER_LBA;
> + AlternateLba = ParentBlockDev->LastBlock;
> + } else {
> + Lba = ParentBlockDev->LastBlock;
> + AlternateLba = PRIMARY_PART_HEADER_LBA;
> + }
> +
> + if ( (PartHdr->Header.Signature != EFI_PTAB_HEADER_ID) ||
> + (PartHdr->Header.Revision != 0x00010000) ||
> + (PartHdr->Header.HeaderSize < 92) ||
> + (PartHdr->Header.HeaderSize > ParentBlockDev->BlockSize) ||
> + (!PartitionCheckGptHeaderCRC (PartHdr)) ||
> + (PartHdr->Header.Reserved != 0)
> + ) {
> + DEBUG ((DEBUG_ERROR, "Invalid efi partition table header\n"));
> + return FALSE;
> + }
> +
> + //
> + // | Block0 | Block1 |Block2 ~ FirstUsableLBA -
> 1|FirstUsableLBA, ... ,LastUsableLBA|LastUsableLBA+1 ~ LastBlock-1| LastBlock
> |
> + // |Protective MBR|Primary Header|Entry Array(At Least 16384)|
> Partition | Entry Array(At Least 16384) |BackUp Header|
> + //
> + // 1. Protective MBR is fixed at Block 0.
> + // 2. Primary Header is fixed at Block 1.
> + // 3. Backup Header is fixed at LastBlock.
> + // 4. Must be remain 128*128 bytes for primary entry array.
> + // 5. Must be remain 128*128 bytes for backup entry array.
> + // 6. SizeOfPartitionEntry must be equals to 128 * 2^n.
> + //
> + if ( (PartHdr->MyLBA != Lba) ||
> + (PartHdr->AlternateLBA != AlternateLba) ||
> + (PartHdr->FirstUsableLBA < 2 + EFI_SIZE_TO_BLOCKS
> (EFI_GPT_PART_ENTRY_MIN_SIZE, ParentBlockDev->BlockSize)) ||
> + (PartHdr->LastUsableLBA > ParentBlockDev->LastBlock - 1 -
> EFI_SIZE_TO_BLOCKS (EFI_GPT_PART_ENTRY_MIN_SIZE, ParentBlockDev-
> >BlockSize)) ||
> + (PartHdr->FirstUsableLBA > PartHdr->LastUsableLBA) ||
> + (PartHdr->PartitionEntryLBA < 2) ||
> + (PartHdr->PartitionEntryLBA > ParentBlockDev->LastBlock - 1) ||
> + (PartHdr->PartitionEntryLBA >= PartHdr->FirstUsableLBA && PartHdr-
> >PartitionEntryLBA <= PartHdr->LastUsableLBA) ||
> + (PartHdr->SizeOfPartitionEntry%128 != 0) ||
> + (PartHdr->SizeOfPartitionEntry != sizeof (EFI_PARTITION_ENTRY))
> + ) {
> + DEBUG ((DEBUG_ERROR, "Invalid efi partition table header\n"));
> + return FALSE;
> + }
> +
> + //
> + // Ensure the NumberOfPartitionEntries * SizeOfPartitionEntry doesn't
> overflow.
> + //
> + if (PartHdr->NumberOfPartitionEntries > DivU64x32 (MAX_UINTN, PartHdr-
> >SizeOfPartitionEntry)) {
> + DEBUG ((DEBUG_ERROR, "Memory overflow in GPT Entry Array\n"));
> + return FALSE;
> + }
> +
> + PartitionEntryArraySize = MultU64x32 (PartHdr->NumberOfPartitionEntries,
> PartHdr->SizeOfPartitionEntry);
> + EntryArraySizeRemainder = 0;
> + PartitionEntryBlockNumb = DivU64x32Remainder (PartitionEntryArraySize,
> ParentBlockDev->BlockSize, &EntryArraySizeRemainder);
> + if (EntryArraySizeRemainder != 0) {
> + PartitionEntryBlockNumb++;
> + }
> +
> + if (IsPrimaryHeader) {
> + EntryArrayLastLba = PartHdr->FirstUsableLBA;
> + } else {
> + EntryArrayLastLba = ParentBlockDev->LastBlock;
> + }
> +
> + //
> + // Make sure partition entry array not overlaps with partition area or the
> LastBlock.
> + //
> + if (PartHdr->PartitionEntryLBA + PartitionEntryBlockNumb >
> EntryArrayLastLba) {
> + DEBUG ((DEBUG_ERROR, "GPT Partition Entry Array Error!\n"));
> + DEBUG ((DEBUG_ERROR, "PartitionEntryArraySize = %lu.\n",
> PartitionEntryArraySize));
> + DEBUG ((DEBUG_ERROR, "PartitionEntryLBA = %lu.\n", PartHdr-
> >PartitionEntryLBA));
> + DEBUG ((DEBUG_ERROR, "PartitionEntryBlockNumb = %lu.\n",
> PartitionEntryBlockNumb));
> + DEBUG ((DEBUG_ERROR, "EntryArrayLastLba = %lu.\n", EntryArrayLastLba));
> + return FALSE;
> + }
> +
> + return TRUE;
> +}
> +
> +/**
> + This function is used to verify each partition in block device.
> +
> + @param[in] PrivateData The global memory map
> + @param[in] ParentBlockDevNo The parent block device
> + @param[in] PartHdr Stores the partition table that is read
> +
> + @retval TRUE The partition is valid
> + @retval FALSE The partition is not valid
> +
> +**/
> +BOOLEAN
> +PartitionCheckGptEntryArray (
> + IN PEI_FAT_PRIVATE_DATA *PrivateData,
> + IN UINTN ParentBlockDevNo,
> + IN EFI_PARTITION_TABLE_HEADER *PartHdr
> + )
> +{
> + EFI_STATUS Status;
> + PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
> + PEI_FAT_BLOCK_DEVICE *BlockDevPtr;
> +
> + UINT64 PartitionEntryArraySize;
> + UINT64 PartitionEntryBlockNumb;
> + UINT32 EntryArraySizeRemainder;
> +
> + EFI_PARTITION_ENTRY *PartitionEntryBuffer;
> + EFI_PARTITION_ENTRY_STATUS *PartitionEntryStatus;
> +
> + BOOLEAN Found;
> + EFI_LBA StartingLBA;
> + EFI_LBA EndingLBA;
> + UINTN Index;
> + UINTN Index1;
> + UINTN Index2;
> + EFI_PARTITION_ENTRY *Entry;
> +
> + ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
> + Found = FALSE;
> +
> + PartitionEntryArraySize = MultU64x32 (PartHdr->NumberOfPartitionEntries,
> PartHdr->SizeOfPartitionEntry);
> + EntryArraySizeRemainder = 0;
> + PartitionEntryBlockNumb = DivU64x32Remainder (PartitionEntryArraySize,
> ParentBlockDev->BlockSize, &EntryArraySizeRemainder);
> + if (EntryArraySizeRemainder != 0) {
> + PartitionEntryBlockNumb++;
> + }
> + PartitionEntryArraySize = MultU64x32 (PartitionEntryBlockNumb,
> ParentBlockDev->BlockSize);
> +
> + PartitionEntryBuffer = (EFI_PARTITION_ENTRY *) AllocatePages
> (EFI_SIZE_TO_PAGES ((UINTN)PartitionEntryArraySize));
> + if (PartitionEntryBuffer == NULL) {
> + DEBUG ((DEBUG_ERROR, "Allocate memory error!\n"));
> + goto EXIT;
> + }
> +
> + PartitionEntryStatus = (EFI_PARTITION_ENTRY_STATUS *) AllocatePages
> (EFI_SIZE_TO_PAGES (PartHdr->NumberOfPartitionEntries * sizeof
> (EFI_PARTITION_ENTRY_STATUS)));
> + if (PartitionEntryStatus == NULL) {
> + DEBUG ((DEBUG_ERROR, "Allocate memory error!\n"));
> + goto EXIT;
> + }
> + ZeroMem (PartitionEntryStatus, PartHdr->NumberOfPartitionEntries * sizeof
> (EFI_PARTITION_ENTRY_STATUS));
> +
> + Status = FatReadBlock (
> + PrivateData,
> + ParentBlockDevNo,
> + PartHdr->PartitionEntryLBA,
> + (UINTN)PartitionEntryArraySize,
> + PartitionEntryBuffer
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "Read partition entry array error!\n"));
> + goto EXIT;
> + }
> +
> + if (!PartitionCheckGptEntryArrayCRC (PartHdr, PartitionEntryBuffer)) {
> + DEBUG ((DEBUG_ERROR, "Partition entries CRC check fail\n"));
> + goto EXIT;
> + }
> +
> + for (Index1 = 0; Index1 < PartHdr->NumberOfPartitionEntries; Index1++) {
> + Entry = (EFI_PARTITION_ENTRY *) ((UINT8 *) PartitionEntryBuffer + Index1
> * PartHdr->SizeOfPartitionEntry);
> + if (CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid)) {
> + continue;
> + }
> +
> + StartingLBA = Entry->StartingLBA;
> + EndingLBA = Entry->EndingLBA;
> + if (StartingLBA > EndingLBA ||
> + StartingLBA < PartHdr->FirstUsableLBA ||
> + StartingLBA > PartHdr->LastUsableLBA ||
> + EndingLBA < PartHdr->FirstUsableLBA ||
> + EndingLBA > PartHdr->LastUsableLBA
> + ) {
> + PartitionEntryStatus[Index1].OutOfRange = TRUE;
> + continue;
> + }
> +
> + if ((Entry->Attributes & BIT1) != 0) {
> + //
> + // If Bit 1 is set, this indicate that this is an OS specific GUID partition.
> + //
> + PartitionEntryStatus[Index1].OsSpecific = TRUE;
> + }
> +
> + for (Index2 = Index1 + 1; Index2 < PartHdr->NumberOfPartitionEntries;
> Index2++) {
> + Entry = (EFI_PARTITION_ENTRY *) ((UINT8 *) PartitionEntryBuffer + Index2
> * PartHdr->SizeOfPartitionEntry);
> + if (CompareGuid (&Entry->PartitionTypeGUID, &gEfiPartTypeUnusedGuid))
> {
> + continue;
> + }
> +
> + if (Entry->EndingLBA >= StartingLBA && Entry->StartingLBA <= EndingLBA)
> {
> + //
> + // This region overlaps with the Index1'th region
> + //
> + PartitionEntryStatus[Index1].Overlap = TRUE;
> + PartitionEntryStatus[Index2].Overlap = TRUE;
> + continue;
> + }
> + }
> + }
> +
> + for (Index = 0; Index < PartHdr->NumberOfPartitionEntries; Index++) {
> + if (CompareGuid (&PartitionEntryBuffer[Index].PartitionTypeGUID,
> &gEfiPartTypeUnusedGuid)||
> + PartitionEntryStatus[Index].OutOfRange ||
> + PartitionEntryStatus[Index].Overlap ||
> + PartitionEntryStatus[Index].OsSpecific) {
> + //
> + // Don't use null EFI Partition Entries, Invalid Partition Entries or OS
> specific
> + // partition Entries
> + //
> + continue;
> + }
> +
> + if (PrivateData->BlockDeviceCount >= PEI_FAT_MAX_BLOCK_DEVICE) {
> + break;
> + }
> +
> + Found = TRUE;
> + BlockDevPtr = &(PrivateData->BlockDevice[PrivateData-
> >BlockDeviceCount]);
> +
> + BlockDevPtr->BlockSize = ParentBlockDev->BlockSize;
> + BlockDevPtr->LastBlock = PartitionEntryBuffer[Index].EndingLBA;
> + BlockDevPtr->IoAlign = ParentBlockDev->IoAlign;
> + BlockDevPtr->Logical = TRUE;
> + BlockDevPtr->PartitionChecked = FALSE;
> + BlockDevPtr->StartingPos = MultU64x32 (
> + PartitionEntryBuffer[Index].StartingLBA,
> + ParentBlockDev->BlockSize
> + );
> + BlockDevPtr->ParentDevNo = ParentBlockDevNo;
> +
> + PrivateData->BlockDeviceCount++;
> +
> + DEBUG ((DEBUG_INFO, "Find GPT Partition [0x%lx",
> PartitionEntryBuffer[Index].StartingLBA, BlockDevPtr->LastBlock));
> + DEBUG ((DEBUG_INFO, ", 0x%lx]\n", BlockDevPtr->LastBlock));
> + DEBUG ((DEBUG_INFO, " BlockSize %x\n", BlockDevPtr->BlockSize));
> + }
> +
> +EXIT:
> + if (PartitionEntryBuffer != NULL) {
> + FreePages (PartitionEntryBuffer, EFI_SIZE_TO_PAGES
> ((UINTN)PartitionEntryArraySize));
> + }
> +
> + if (PartitionEntryStatus != NULL) {
> + FreePages (PartitionEntryStatus, EFI_SIZE_TO_PAGES (PartHdr-
> >NumberOfPartitionEntries * sizeof (EFI_PARTITION_ENTRY_STATUS)));
> + }
> +
> + return Found;
> +}
> +
> +/**
> + The function is used to check GPT structure, include GPT header and GPT
> entry array.
> +
> + 1. Check GPT header.
> + 2. Check partition entry array.
> + 3. Check each partitions.
> +
> + @param[in] PrivateData The global memory map
> + @param[in] ParentBlockDevNo The parent block device
> + @param[in] IsPrimary Indicate primary or backup to be check
> +
> + @retval TRUE Primary or backup GPT structure is valid.
> + @retval FALSE Both primary and backup are invalid.
> +
> +**/
> +BOOLEAN
> +PartitionCheckGptStructure (
> + IN PEI_FAT_PRIVATE_DATA *PrivateData,
> + IN UINTN ParentBlockDevNo,
> + IN BOOLEAN IsPrimary
> + )
> +{
> + EFI_STATUS Status;
> + PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
> + EFI_PARTITION_TABLE_HEADER *PartHdr;
> + EFI_PEI_LBA GptHeaderLBA;
> +
> + ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
> + PartHdr = (EFI_PARTITION_TABLE_HEADER *) PrivateData->BlockData;
> +
> + if (IsPrimary) {
> + GptHeaderLBA = PRIMARY_PART_HEADER_LBA;
> + } else {
> + GptHeaderLBA = ParentBlockDev->LastBlock;
> + }
> +
> + Status = FatReadBlock (
> + PrivateData,
> + ParentBlockDevNo,
> + GptHeaderLBA,
> + ParentBlockDev->BlockSize,
> + PartHdr
> + );
> + if (EFI_ERROR (Status)) {
> + return FALSE;
> + }
> +
> + if (!PartitionCheckGptHeader (PrivateData, ParentBlockDevNo, IsPrimary,
> PartHdr)) {
> + return FALSE;
> + }
> +
> + if (!PartitionCheckGptEntryArray (PrivateData, ParentBlockDevNo, PartHdr))
> {
> + return FALSE;
> + }
> +
> + return TRUE;
> +}
> +
> +/**
> + This function is used to check protective MBR structure before checking GPT.
> +
> + @param[in] PrivateData The global memory map
> + @param[in] ParentBlockDevNo The parent block device
> +
> + @retval TRUE Valid protective MBR
> + @retval FALSE Invalid MBR
> +**/
> +BOOLEAN
> +PartitionCheckProtectiveMbr (
> + IN PEI_FAT_PRIVATE_DATA *PrivateData,
> + IN UINTN ParentBlockDevNo
> + )
> +{
> + EFI_STATUS Status;
> + MASTER_BOOT_RECORD *ProtectiveMbr;
> + MBR_PARTITION_RECORD *MbrPartition;
> + PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
> + UINTN Index;
> +
> + ProtectiveMbr = (MASTER_BOOT_RECORD *) PrivateData->BlockData;
> + ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
> +
> + //
> + // Read Protective MBR
> + //
> + Status = FatReadBlock (
> + PrivateData,
> + ParentBlockDevNo,
> + 0,
> + ParentBlockDev->BlockSize,
> + ProtectiveMbr
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "GPT Error When Read Protective Mbr From
> Partition!\n"));
> + return FALSE;
> + }
> +
> + if (ProtectiveMbr->Signature != MBR_SIGNATURE) {
> + DEBUG ((DEBUG_ERROR, "Protective Mbr Signature is invalid!\n"));
> + return FALSE;
> + }
> +
> + //
> + // The partition define in UEFI Spec Table 17.
> + // Boot Code, Unique MBR Disk Signature, Unknown.
> + // These parts will not be used by UEFI, so we skip to check them.
> + //
> + for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
> + MbrPartition = (MBR_PARTITION_RECORD *)&ProtectiveMbr-
> >Partition[Index];
> + if (MbrPartition->BootIndicator == 0x00 &&
> + MbrPartition->StartSector == 0x02 &&
> + MbrPartition->OSIndicator == PMBR_GPT_PARTITION &&
> + UNPACK_UINT32 (MbrPartition->StartingLBA) == 1
> + ) {
> + return TRUE;
> + }
> + }
> +
> + DEBUG ((DEBUG_ERROR, "Protective Mbr, All Partition Entry Are
> Empty!\n"));
> + return FALSE;
> +}
> +
> +/**
> + This function is used for finding GPT partition on block device.
> + As follow UEFI spec we should check protective MBR first and then
> + try to check both primary/backup GPT structures.
> +
> + @param[in] PrivateData The global memory map
> + @param[in] ParentBlockDevNo The parent block device
> +
> + @retval TRUE New partitions are detected and logical block devices
> + are added to block device array
> + @retval FALSE No new partitions are added
> +
> +**/
> +BOOLEAN
> +FatFindGptPartitions (
> + IN PEI_FAT_PRIVATE_DATA *PrivateData,
> + IN UINTN ParentBlockDevNo
> + )
> +{
> + BOOLEAN Found;
> + PEI_FAT_BLOCK_DEVICE *ParentBlockDev;
> +
> + if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
> + return FALSE;
> + }
> +
> + ParentBlockDev = &(PrivateData->BlockDevice[ParentBlockDevNo]);
> + if (ParentBlockDev->BlockSize > PEI_FAT_MAX_BLOCK_SIZE) {
> + DEBUG ((DEBUG_ERROR, "Device BlockSize %x exceed
> FAT_MAX_BLOCK_SIZE\n", ParentBlockDev->BlockSize));
> + return FALSE;
> + }
> +
> + if (!PartitionCheckProtectiveMbr (PrivateData, ParentBlockDevNo)) {
> + return FALSE;
> + }
> +
> + Found = PartitionCheckGptStructure (PrivateData, ParentBlockDevNo, TRUE);
> + if (!Found) {
> + DEBUG ((DEBUG_ERROR, "Primary GPT Header Error, Try to Check Backup
> GPT Header!\n"));
> + Found = PartitionCheckGptStructure (PrivateData, ParentBlockDevNo,
> FALSE);
> + }
> +
> + if (Found) {
> + ParentBlockDev->PartitionChecked = TRUE;
> + }
> +
> + return Found;
> +}
> diff --git a/FatPkg/FatPei/Part.c b/FatPkg/FatPei/Part.c
> index 8a54e56f5a..9b49eccf4e 100644
> --- a/FatPkg/FatPei/Part.c
> +++ b/FatPkg/FatPei/Part.c
> @@ -52,6 +52,25 @@ FatFindMbrPartitions (
> IN UINTN ParentBlockDevNo
> );
>
> +/**
> + This function is used for finding GPT partition on block device.
> + As follow UEFI spec we should check protective MBR first and then
> + try to check both primary/backup GPT structures.
> +
> + @param[in] PrivateData The global memory map
> + @param[in] ParentBlockDevNo The parent block device
> +
> + @retval TRUE New partitions are detected and logical block devices
> + are added to block device array
> + @retval FALSE No new partitions are added
> +
> +**/
> +BOOLEAN
> +FatFindGptPartitions (
> + IN PEI_FAT_PRIVATE_DATA *PrivateData,
> + IN UINTN ParentBlockDevNo
> + );
> +
> /**
> This function finds partitions (logical devices) in physical block devices.
>
> @@ -71,12 +90,21 @@ FatFindPartitions (
>
> for (Index = 0; Index < PrivateData->BlockDeviceCount; Index++) {
> if (!PrivateData->BlockDevice[Index].PartitionChecked) {
> - Found = FatFindMbrPartitions (PrivateData, Index);
> - if (!Found) {
> - Found = FatFindEltoritoPartitions (PrivateData, Index);
> + if (FatFindGptPartitions (PrivateData, Index)) {
> + Found = TRUE;
> + continue;
> + }
> +
> + if (FatFindMbrPartitions (PrivateData, Index)) {
> + Found = TRUE;
> + continue;
> + }
> +
> + if (FatFindEltoritoPartitions (PrivateData, Index)) {
> + Found = TRUE;
> + continue;
> }
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
Best Regards,
Hao Wu
> }
> }
> } while (Found && PrivateData->BlockDeviceCount <=
> PEI_FAT_MAX_BLOCK_DEVICE);
> }
> -
> --
> 2.16.2.windows.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3
2019-01-29 5:27 [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3 Chen A Chen
` (2 preceding siblings ...)
2019-01-29 5:27 ` [PATCH v3 3/3] FatPkg: Add GPT check in FatPei to support Capsule-on-Disk feature Chen A Chen
@ 2019-01-31 3:13 ` Wu, Hao A
3 siblings, 0 replies; 6+ messages in thread
From: Wu, Hao A @ 2019-01-31 3:13 UTC (permalink / raw)
To: Chen, Chen A, edk2-devel@lists.01.org
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Chen
> A Chen
> Sent: Tuesday, January 29, 2019 1:28 PM
> To: edk2-devel@lists.01.org
> Subject: [edk2] [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3
>
> No function change, fix code style issue.
Thanks for the contribution.
Series has been pushed @8a9301cdd7..0d18f5db32.
Best Regards,
Hao Wu
>
> Chen A Chen (3):
> FatPkg: Break down Part.c file.
> MdePkg/UefiGpt.h: Add new definition for enable GPT support
> FatPkg: Add GPT check in FatPei to support Capsule-on-Disk feature.
>
> FatPkg/FatPei/Eltorito.c | 239 ++++++++++++++++++
> FatPkg/FatPei/FatLitePeim.h | 3 +-
> FatPkg/FatPei/FatPei.inf | 7 +-
> FatPkg/FatPei/Gpt.c | 548
> ++++++++++++++++++++++++++++++++++++++++++
> FatPkg/FatPei/Mbr.c | 181 ++++++++++++++
> FatPkg/FatPei/Part.c | 434 +++------------------------------
> MdePkg/Include/Uefi/UefiGpt.h | 6 +-
> 7 files changed, 1020 insertions(+), 398 deletions(-)
> create mode 100644 FatPkg/FatPei/Eltorito.c
> create mode 100644 FatPkg/FatPei/Gpt.c
> create mode 100644 FatPkg/FatPei/Mbr.c
>
> --
> 2.16.2.windows.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-01-31 3:14 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-29 5:27 [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3 Chen A Chen
2019-01-29 5:27 ` [PATCH v3 1/3] FatPkg: Break down Part.c file Chen A Chen
2019-01-29 5:27 ` [PATCH v3 2/3] MdePkg/UefiGpt.h: Add new definition for enable GPT support Chen A Chen
2019-01-29 5:27 ` [PATCH v3 3/3] FatPkg: Add GPT check in FatPei to support Capsule-on-Disk feature Chen A Chen
2019-01-30 8:37 ` Wu, Hao A
2019-01-31 3:13 ` [PATCH v2 0/3] FatPkg/GPT: Introduce GPT patch v3 Wu, Hao A
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox