Changeset 80721 in vbox for trunk/src/VBox/Devices/EFI/FirmwareNew/FatPkg/FatPei/Part.c
- Timestamp:
- Sep 11, 2019 8:46:37 AM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 133262
- Location:
- trunk/src/VBox/Devices/EFI/FirmwareNew
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/FirmwareNew
-
Property svn:mergeinfo
changed from (toggle deleted branches)
to (toggle deleted branches)/vendor/edk2/current 103735-103757,103769-103776,129194-129237 /vendor/edk2/current 103735-103757,103769-103776,129194-133213
-
Property svn:mergeinfo
changed from (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/FirmwareNew/FatPkg/FatPei/Part.c
r77662 r80721 3 3 logical device reading 4 4 5 Copyright (c) 2006 - 20 08, Intel Corporation. All rights reserved.<BR>5 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR> 6 6 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. 7 SPDX-License-Identifier: BSD-2-Clause-Patent 14 8 15 9 **/ 16 10 17 #include <IndustryStandard/Mbr.h>18 #include <IndustryStandard/ElTorito.h>19 11 #include "FatLitePeim.h" 20 12 … … 23 15 is ported from DXE partition driver. 24 16 25 @param PrivateData The global memory map26 @param ParentBlockDevNo The parent block device17 @param[in] PrivateData The global memory map 18 @param[in] ParentBlockDevNo The parent block device 27 19 28 20 @retval TRUE New partitions are detected and logical block devices 29 are 30 @retval FALSE No New partitions are added;21 are added to block device array 22 @retval FALSE No new partitions are added 31 23 32 24 **/ … … 41 33 is ported from DXE partition driver. 42 34 43 @param PrivateData The global memory map44 @param ParentBlockDevNo The parent block device35 @param[in] PrivateData The global memory map 36 @param[in] ParentBlockDevNo The parent block device 45 37 46 38 @retval TRUE New partitions are detected and logical block devices 47 are 48 @retval FALSE No New partitions are added;39 are added to block device array 40 @retval FALSE No new partitions are added 49 41 50 42 **/ … … 55 47 ); 56 48 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 **/ 62 BOOLEAN 63 FatFindGptPartitions ( 64 IN PEI_FAT_PRIVATE_DATA *PrivateData, 65 IN UINTN ParentBlockDevNo 66 ); 57 67 58 68 /** … … 75 85 for (Index = 0; Index < PrivateData->BlockDeviceCount; Index++) { 76 86 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; 80 100 } 81 101 } … … 83 103 } while (Found && PrivateData->BlockDeviceCount <= PEI_FAT_MAX_BLOCK_DEVICE); 84 104 } 85 86 87 /**88 This function finds Eltorito partitions. Main algorithm89 is ported from DXE partition driver.90 91 @param PrivateData The global memory map92 @param ParentBlockDevNo The parent block device93 94 @retval TRUE New partitions are detected and logical block devices95 are added to block device array96 @retval FALSE No New partitions are added;97 98 **/99 BOOLEAN100 FatFindEltoritoPartitions (101 IN PEI_FAT_PRIVATE_DATA *PrivateData,102 IN UINTN ParentBlockDevNo103 )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 bytes131 //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 media141 // 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 time148 //149 while (TRUE) {150 151 VolDescriptorLba += 1;152 if (VolDescriptorLba > ParentBlockDev->LastBlock) {153 //154 // We are pointing past the end of the device so exit155 //156 break;157 }158 159 Status = FatReadBlock (160 PrivateData,161 ParentBlockDevNo,162 VolDescriptorLba,163 ParentBlockDev->BlockSize,164 VolDescriptor165 );166 if (EFI_ERROR (Status)) {167 break;168 }169 //170 // Check for valid volume descriptor signature171 //172 if (VolDescriptor->Unknown.Type == CDVOL_TYPE_END ||173 CompareMem (VolDescriptor->Unknown.Id, CDVOL_ID, sizeof (VolDescriptor->Unknown.Id)) != 0174 ) {175 //176 // end of Volume descriptor list177 //178 break;179 }180 //181 // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte182 //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) - 1193 ) != 0) {194 continue;195 }196 //197 // Read in the boot El Torito boot catalog198 //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 Catalog210 );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 want216 // to make sure it looks like a Catalog header217 //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 entry236 //237 Catalog += 1;238 239 //240 // Check this entry241 //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 partition282 //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 MBR311 312 @param Mbr Parent Handle313 @param LastLba Last Lba address on the device.314 315 @retval TRUE Mbr is a Valid MBR316 @retval FALSE Mbr is not a Valid MBR317 318 **/319 BOOLEAN320 PartitionValidMbr (321 IN MASTER_BOOT_RECORD *Mbr,322 IN EFI_PEI_LBA LastLba323 )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 driver351 // This does not hide space from the OS driver. This means the MBR352 // that gets created from DOS is smaller than the MBR created from353 // a real OS (NT & Win98). This leads to BlockIo->LastBlock being354 // wrong on some systems FDISKed by the OS.355 //356 // return FALSE Because no block devices on a system are implemented357 // with INT 13h358 //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 region371 //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 algorithm385 is ported from DXE partition driver.386 387 @param PrivateData The global memory map388 @param ParentBlockDevNo The parent block device389 390 @retval TRUE New partitions are detected and logical block devices391 are added to block device array392 @retval FALSE No New partitions are added;393 394 **/395 BOOLEAN396 FatFindMbrPartitions (397 IN PEI_FAT_PRIVATE_DATA *PrivateData,398 IN UINTN ParentBlockDevNo399 )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 Mbr423 );424 425 if (EFI_ERROR (Status) || !PartitionValidMbr (Mbr, ParentBlockDev->LastBlock)) {426 goto Done;427 }428 //429 // We have a valid mbr - add each partition430 //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 entries435 //436 continue;437 }438 //439 // Register this partition440 //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->BlockSize455 );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.