123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- /** @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/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;
- }
|