123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /** @file
- Routines supporting partition discovery and
- logical device reading
- Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #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;
- }
|