VirtualBox

Ignore:
Timestamp:
Sep 11, 2019 8:46:37 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
133262
Message:

Devices/EFI/FirmwareNew: Start upgrade process to edk2-stable201908 (compiles on Windows and works to some extent), bugref:4643

Location:
trunk/src/VBox/Devices/EFI/FirmwareNew
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/FirmwareNew

  • trunk/src/VBox/Devices/EFI/FirmwareNew/FatPkg/FatPei/Part.c

    r77662 r80721  
    33  logical device reading
    44
    5 Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
     5Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
    66
    7 This program and the accompanying materials are licensed and made available
    8 under the terms and conditions of the BSD License which accompanies this
    9 distribution. The full text of the license may be found at
    10 http://opensource.org/licenses/bsd-license.php
    11 
    12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
    13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     7SPDX-License-Identifier: BSD-2-Clause-Patent
    148
    159**/
    1610
    17 #include <IndustryStandard/Mbr.h>
    18 #include <IndustryStandard/ElTorito.h>
    1911#include "FatLitePeim.h"
    2012
     
    2315  is ported from DXE partition driver.
    2416
    25   @param  PrivateData       The global memory map
    26   @param  ParentBlockDevNo  The parent block device
     17  @param[in]  PrivateData       The global memory map
     18  @param[in]  ParentBlockDevNo  The parent block device
    2719
    2820  @retval TRUE              New partitions are detected and logical block devices
    29                             are  added to block device array
    30   @retval FALSE             No New partitions are added;
     21                            are added to block device array
     22  @retval FALSE             No new partitions are added
    3123
    3224**/
     
    4133  is ported from DXE partition driver.
    4234
    43   @param  PrivateData       The global memory map
    44   @param  ParentBlockDevNo  The parent block device
     35  @param[in]  PrivateData       The global memory map
     36  @param[in]  ParentBlockDevNo  The parent block device
    4537
    4638  @retval TRUE              New partitions are detected and logical block devices
    47                             are  added to block device array
    48   @retval FALSE             No New partitions are added;
     39                            are added to block device array
     40  @retval FALSE             No new partitions are added
    4941
    5042**/
     
    5547  );
    5648
     49/**
     50  This function is used for finding GPT partition on block device.
     51  As follow UEFI spec we should check protective MBR first and then
     52  try to check both primary/backup GPT structures.
     53
     54  @param[in]  PrivateData       The global memory map
     55  @param[in]  ParentBlockDevNo  The parent block device
     56
     57  @retval TRUE              New partitions are detected and logical block devices
     58                            are added to block device array
     59  @retval FALSE             No new partitions are added
     60
     61**/
     62BOOLEAN
     63FatFindGptPartitions (
     64  IN  PEI_FAT_PRIVATE_DATA *PrivateData,
     65  IN  UINTN                ParentBlockDevNo
     66  );
    5767
    5868/**
     
    7585    for (Index = 0; Index < PrivateData->BlockDeviceCount; Index++) {
    7686      if (!PrivateData->BlockDevice[Index].PartitionChecked) {
    77         Found = FatFindMbrPartitions (PrivateData, Index);
    78         if (!Found) {
    79           Found = FatFindEltoritoPartitions (PrivateData, Index);
     87        if (FatFindGptPartitions (PrivateData, Index)) {
     88          Found = TRUE;
     89          continue;
     90        }
     91
     92        if (FatFindMbrPartitions (PrivateData, Index)) {
     93          Found = TRUE;
     94          continue;
     95        }
     96
     97        if (FatFindEltoritoPartitions (PrivateData, Index)) {
     98          Found = TRUE;
     99          continue;
    80100        }
    81101      }
     
    83103  } while (Found && PrivateData->BlockDeviceCount <= PEI_FAT_MAX_BLOCK_DEVICE);
    84104}
    85 
    86 
    87 /**
    88   This function finds Eltorito partitions. Main algorithm
    89   is ported from DXE partition driver.
    90 
    91   @param  PrivateData       The global memory map
    92   @param  ParentBlockDevNo  The parent block device
    93 
    94   @retval TRUE              New partitions are detected and logical block devices
    95                             are  added to block device array
    96   @retval FALSE             No New partitions are added;
    97 
    98 **/
    99 BOOLEAN
    100 FatFindEltoritoPartitions (
    101   IN  PEI_FAT_PRIVATE_DATA *PrivateData,
    102   IN  UINTN                ParentBlockDevNo
    103   )
    104 {
    105   EFI_STATUS              Status;
    106   BOOLEAN                 Found;
    107   PEI_FAT_BLOCK_DEVICE    *BlockDev;
    108   PEI_FAT_BLOCK_DEVICE    *ParentBlockDev;
    109   UINT32                  VolDescriptorLba;
    110   UINT32                  Lba;
    111   CDROM_VOLUME_DESCRIPTOR *VolDescriptor;
    112   ELTORITO_CATALOG        *Catalog;
    113   UINTN                   Check;
    114   UINTN                   Index;
    115   UINTN                   MaxIndex;
    116   UINT16                  *CheckBuffer;
    117   UINT32                  SubBlockSize;
    118   UINT32                  SectorCount;
    119   UINT32                  VolSpaceSize;
    120 
    121   if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
    122     return FALSE;
    123   }
    124 
    125   Found           = FALSE;
    126   ParentBlockDev  = &(PrivateData->BlockDevice[ParentBlockDevNo]);
    127   VolSpaceSize    = 0;
    128 
    129   //
    130   // CD_ROM has the fixed block size as 2048 bytes
    131   //
    132   if (ParentBlockDev->BlockSize != 2048) {
    133     return FALSE;
    134   }
    135 
    136   VolDescriptor = (CDROM_VOLUME_DESCRIPTOR *) PrivateData->BlockData;
    137   Catalog       = (ELTORITO_CATALOG *) VolDescriptor;
    138 
    139   //
    140   // the ISO-9660 volume descriptor starts at 32k on the media
    141   // and CD_ROM has the fixed block size as 2048 bytes, so...
    142   //
    143   VolDescriptorLba = 15;
    144   //
    145   // ((16*2048) / Media->BlockSize) - 1;
    146   //
    147   // Loop: handle one volume descriptor per time
    148   //
    149   while (TRUE) {
    150 
    151     VolDescriptorLba += 1;
    152     if (VolDescriptorLba > ParentBlockDev->LastBlock) {
    153       //
    154       // We are pointing past the end of the device so exit
    155       //
    156       break;
    157     }
    158 
    159     Status = FatReadBlock (
    160               PrivateData,
    161               ParentBlockDevNo,
    162               VolDescriptorLba,
    163               ParentBlockDev->BlockSize,
    164               VolDescriptor
    165               );
    166     if (EFI_ERROR (Status)) {
    167       break;
    168     }
    169     //
    170     // Check for valid volume descriptor signature
    171     //
    172     if (VolDescriptor->Unknown.Type == CDVOL_TYPE_END ||
    173         CompareMem (VolDescriptor->Unknown.Id, CDVOL_ID, sizeof (VolDescriptor->Unknown.Id)) != 0
    174         ) {
    175       //
    176       // end of Volume descriptor list
    177       //
    178       break;
    179     }
    180     //
    181     // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte
    182     //
    183     if (VolDescriptor->Unknown.Type == CDVOL_TYPE_CODED) {
    184       VolSpaceSize = VolDescriptor->PrimaryVolume.VolSpaceSize[1];
    185     }
    186     //
    187     // Is it an El Torito volume descriptor?
    188     //
    189     if (CompareMem (
    190           VolDescriptor->BootRecordVolume.SystemId,
    191           CDVOL_ELTORITO_ID,
    192           sizeof (CDVOL_ELTORITO_ID) - 1
    193           ) != 0) {
    194       continue;
    195     }
    196     //
    197     // Read in the boot El Torito boot catalog
    198     //
    199     Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);
    200     if (Lba > ParentBlockDev->LastBlock) {
    201       continue;
    202     }
    203 
    204     Status = FatReadBlock (
    205               PrivateData,
    206               ParentBlockDevNo,
    207               Lba,
    208               ParentBlockDev->BlockSize,
    209               Catalog
    210               );
    211     if (EFI_ERROR (Status)) {
    212       continue;
    213     }
    214     //
    215     // We don't care too much about the Catalog header's contents, but we do want
    216     // to make sure it looks like a Catalog header
    217     //
    218     if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {
    219       continue;
    220     }
    221 
    222     Check       = 0;
    223     CheckBuffer = (UINT16 *) Catalog;
    224     for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {
    225       Check += CheckBuffer[Index];
    226     }
    227 
    228     if ((Check & 0xFFFF) != 0) {
    229       continue;
    230     }
    231 
    232     MaxIndex = ParentBlockDev->BlockSize / sizeof (ELTORITO_CATALOG);
    233     for (Index = 1; Index < MaxIndex; Index += 1) {
    234       //
    235       // Next entry
    236       //
    237       Catalog += 1;
    238 
    239       //
    240       // Check this entry
    241       //
    242       if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {
    243         continue;
    244       }
    245 
    246       SubBlockSize  = 512;
    247       SectorCount   = Catalog->Boot.SectorCount;
    248 
    249       switch (Catalog->Boot.MediaType) {
    250 
    251       case ELTORITO_NO_EMULATION:
    252         SubBlockSize  = ParentBlockDev->BlockSize;
    253         SectorCount   = Catalog->Boot.SectorCount;
    254         break;
    255 
    256       case ELTORITO_HARD_DISK:
    257         break;
    258 
    259       case ELTORITO_12_DISKETTE:
    260         SectorCount = 0x50 * 0x02 * 0x0F;
    261         break;
    262 
    263       case ELTORITO_14_DISKETTE:
    264         SectorCount = 0x50 * 0x02 * 0x12;
    265         break;
    266 
    267       case ELTORITO_28_DISKETTE:
    268         SectorCount = 0x50 * 0x02 * 0x24;
    269         break;
    270 
    271       default:
    272         SectorCount   = 0;
    273         SubBlockSize  = ParentBlockDev->BlockSize;
    274         break;
    275       }
    276 
    277       if (SectorCount < 2) {
    278         SectorCount = (VolSpaceSize > ParentBlockDev->LastBlock + 1) ? (UINT32) (ParentBlockDev->LastBlock - Catalog->Boot.Lba + 1) : (UINT32) (VolSpaceSize - Catalog->Boot.Lba);
    279       }
    280       //
    281       // Register this partition
    282       //
    283       if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {
    284 
    285         Found                       = TRUE;
    286 
    287         BlockDev                    = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);
    288 
    289         BlockDev->BlockSize         = SubBlockSize;
    290         BlockDev->LastBlock         = SectorCount - 1;
    291         BlockDev->IoAlign           = ParentBlockDev->IoAlign;
    292         BlockDev->Logical           = TRUE;
    293         BlockDev->PartitionChecked  = FALSE;
    294         BlockDev->StartingPos       = MultU64x32 (Catalog->Boot.Lba, ParentBlockDev->BlockSize);
    295         BlockDev->ParentDevNo       = ParentBlockDevNo;
    296 
    297         PrivateData->BlockDeviceCount++;
    298       }
    299     }
    300   }
    301 
    302   ParentBlockDev->PartitionChecked = TRUE;
    303 
    304   return Found;
    305 
    306 }
    307 
    308 
    309 /**
    310   Test to see if the Mbr buffer is a valid MBR
    311 
    312   @param  Mbr               Parent Handle
    313   @param  LastLba           Last Lba address on the device.
    314 
    315   @retval TRUE              Mbr is a Valid MBR
    316   @retval FALSE             Mbr is not a Valid MBR
    317 
    318 **/
    319 BOOLEAN
    320 PartitionValidMbr (
    321   IN  MASTER_BOOT_RECORD      *Mbr,
    322   IN  EFI_PEI_LBA             LastLba
    323   )
    324 {
    325   UINT32  StartingLBA;
    326   UINT32  EndingLBA;
    327   UINT32  NewEndingLBA;
    328   INTN    Index1;
    329   INTN    Index2;
    330   BOOLEAN MbrValid;
    331 
    332   if (Mbr->Signature != MBR_SIGNATURE) {
    333     return FALSE;
    334   }
    335   //
    336   // The BPB also has this signature, so it can not be used alone.
    337   //
    338   MbrValid = FALSE;
    339   for (Index1 = 0; Index1 < MAX_MBR_PARTITIONS; Index1++) {
    340     if (Mbr->Partition[Index1].OSIndicator == 0x00 || UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) == 0) {
    341       continue;
    342     }
    343 
    344     MbrValid    = TRUE;
    345     StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);
    346     EndingLBA   = StartingLBA + UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA) - 1;
    347     if (EndingLBA > LastLba) {
    348       //
    349       // Compatability Errata:
    350       //  Some systems try to hide drive space with thier INT 13h driver
    351       //  This does not hide space from the OS driver. This means the MBR
    352       //  that gets created from DOS is smaller than the MBR created from
    353       //  a real OS (NT & Win98). This leads to BlockIo->LastBlock being
    354       //  wrong on some systems FDISKed by the OS.
    355       //
    356       //  return FALSE Because no block devices on a system are implemented
    357       //  with INT 13h
    358       //
    359       return FALSE;
    360     }
    361 
    362     for (Index2 = Index1 + 1; Index2 < MAX_MBR_PARTITIONS; Index2++) {
    363       if (Mbr->Partition[Index2].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index2].SizeInLBA) == 0) {
    364         continue;
    365       }
    366 
    367       NewEndingLBA = UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) + UNPACK_UINT32 (Mbr->Partition[Index2].SizeInLBA) - 1;
    368       if (NewEndingLBA >= StartingLBA && UNPACK_UINT32 (Mbr->Partition[Index2].StartingLBA) <= EndingLBA) {
    369         //
    370         // This region overlaps with the Index1'th region
    371         //
    372         return FALSE;
    373       }
    374     }
    375   }
    376   //
    377   // Non of the regions overlapped so MBR is O.K.
    378   //
    379   return MbrValid;
    380 }
    381 
    382 
    383 /**
    384   This function finds Mbr partitions. Main algorithm
    385   is ported from DXE partition driver.
    386 
    387   @param  PrivateData       The global memory map
    388   @param  ParentBlockDevNo  The parent block device
    389 
    390   @retval TRUE              New partitions are detected and logical block devices
    391                             are  added to block device array
    392   @retval FALSE             No New partitions are added;
    393 
    394 **/
    395 BOOLEAN
    396 FatFindMbrPartitions (
    397   IN  PEI_FAT_PRIVATE_DATA *PrivateData,
    398   IN  UINTN                ParentBlockDevNo
    399   )
    400 {
    401   EFI_STATUS            Status;
    402   MASTER_BOOT_RECORD    *Mbr;
    403   UINTN                 Index;
    404   BOOLEAN               Found;
    405   PEI_FAT_BLOCK_DEVICE  *ParentBlockDev;
    406   PEI_FAT_BLOCK_DEVICE  *BlockDev;
    407 
    408   if (ParentBlockDevNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
    409     return FALSE;
    410   }
    411 
    412   ParentBlockDev  = &(PrivateData->BlockDevice[ParentBlockDevNo]);
    413 
    414   Found           = FALSE;
    415   Mbr             = (MASTER_BOOT_RECORD *) PrivateData->BlockData;
    416 
    417   Status = FatReadBlock (
    418             PrivateData,
    419             ParentBlockDevNo,
    420             0,
    421             ParentBlockDev->BlockSize,
    422             Mbr
    423             );
    424 
    425   if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, ParentBlockDev->LastBlock)) {
    426     goto Done;
    427   }
    428   //
    429   // We have a valid mbr - add each partition
    430   //
    431   for (Index = 0; Index < MAX_MBR_PARTITIONS; Index++) {
    432     if (Mbr->Partition[Index].OSIndicator == 0x00 || UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) == 0) {
    433       //
    434       // Don't use null MBR entries
    435       //
    436       continue;
    437     }
    438     //
    439     // Register this partition
    440     //
    441     if (PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE) {
    442 
    443       Found                       = TRUE;
    444 
    445       BlockDev                    = &(PrivateData->BlockDevice[PrivateData->BlockDeviceCount]);
    446 
    447       BlockDev->BlockSize         = MBR_SIZE;
    448       BlockDev->LastBlock         = UNPACK_INT32 (Mbr->Partition[Index].SizeInLBA) - 1;
    449       BlockDev->IoAlign           = ParentBlockDev->IoAlign;
    450       BlockDev->Logical           = TRUE;
    451       BlockDev->PartitionChecked  = FALSE;
    452       BlockDev->StartingPos = MultU64x32 (
    453                                 UNPACK_INT32 (Mbr->Partition[Index].StartingLBA),
    454                                 ParentBlockDev->BlockSize
    455                                 );
    456       BlockDev->ParentDevNo = ParentBlockDevNo;
    457 
    458       PrivateData->BlockDeviceCount++;
    459     }
    460   }
    461 
    462 Done:
    463 
    464   ParentBlockDev->PartitionChecked = TRUE;
    465   return Found;
    466 }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette