MdeModulePkg/PartitionDxe: Fixed El Torito support when the medium is not a CDROM

El Torito format can be used on different media (eg: USB).
A ISO image can be dumped onto a USB mass-storage.

These media might not have the same block size as the CDROM media (ie: 2KB).
The El Torito code and the specification assumes a LBA 2KB.

In addition, the specification says in "12.3.4.4 CD-ROM and DVD-ROM":
UEFI code does not assume a fixed block size.

I was able to dupliacte the issue by copying a debian ISO on a USB driver.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16600 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Olivier Martin 2015-01-12 12:28:36 +00:00 committed by oliviermartin
parent 3cbfba02fe
commit 5d6bf9e229
1 changed files with 25 additions and 33 deletions

View File

@ -45,8 +45,8 @@ PartitionInstallElToritoChildHandles (
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT32 VolDescriptorLba; UINT64 VolDescriptorOffset;
UINT32 Lba; UINT32 Lba2KB;
EFI_BLOCK_IO_MEDIA *Media; EFI_BLOCK_IO_MEDIA *Media;
CDROM_VOLUME_DESCRIPTOR *VolDescriptor; CDROM_VOLUME_DESCRIPTOR *VolDescriptor;
ELTORITO_CATALOG *Catalog; ELTORITO_CATALOG *Catalog;
@ -67,13 +67,17 @@ PartitionInstallElToritoChildHandles (
VolSpaceSize = 0; VolSpaceSize = 0;
// //
// CD_ROM has the fixed block size as 2048 bytes // CD_ROM has the fixed block size as 2048 bytes (SIZE_2KB)
// //
if (Media->BlockSize != 2048) {
// If the ISO image has been copied onto a different storage media
// then the block size might be different (eg: USB).
// Ensure 2048 (SIZE_2KB) is a multiple of block size
if (((SIZE_2KB % Media->BlockSize) != 0) || (Media->BlockSize > SIZE_2KB)) {
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
VolDescriptor = AllocatePool ((UINTN) Media->BlockSize); VolDescriptor = AllocatePool ((UINTN)SIZE_2KB);
if (VolDescriptor == NULL) { if (VolDescriptor == NULL) {
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
@ -81,32 +85,18 @@ PartitionInstallElToritoChildHandles (
Catalog = (ELTORITO_CATALOG *) VolDescriptor; 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...
//
//
// ((16*2048) / Media->BlockSize) - 1;
//
VolDescriptorLba = 15;
// //
// Loop: handle one volume descriptor per time // Loop: handle one volume descriptor per time
// The ISO-9660 volume descriptor starts at 32k on the media
// //
while (TRUE) { for (VolDescriptorOffset = SIZE_32KB;
VolDescriptorOffset <= MultU64x32 (Media->LastBlock, Media->BlockSize);
VolDescriptorLba += 1; VolDescriptorOffset += SIZE_2KB) {
if (VolDescriptorLba > Media->LastBlock) {
//
// We are pointing past the end of the device so exit
//
break;
}
Status = DiskIo->ReadDisk ( Status = DiskIo->ReadDisk (
DiskIo, DiskIo,
Media->MediaId, Media->MediaId,
MultU64x32 (VolDescriptorLba, Media->BlockSize), VolDescriptorOffset,
Media->BlockSize, SIZE_2KB,
VolDescriptor VolDescriptor
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@ -139,17 +129,19 @@ PartitionInstallElToritoChildHandles (
} }
// //
// Read in the boot El Torito boot catalog // Read in the boot El Torito boot catalog
// The LBA unit used by El Torito boot catalog is 2KB unit
// //
Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog); Lba2KB = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);
if (Lba > Media->LastBlock) { // Ensure the LBA (in 2KB unit) fits into our media
if (Lba2KB * (SIZE_2KB / Media->BlockSize) > Media->LastBlock) {
continue; continue;
} }
Status = DiskIo->ReadDisk ( Status = DiskIo->ReadDisk (
DiskIo, DiskIo,
Media->MediaId, Media->MediaId,
MultU64x32 (Lba, Media->BlockSize), MultU64x32 (Lba2KB, SIZE_2KB),
Media->BlockSize, SIZE_2KB,
Catalog Catalog
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@ -191,7 +183,7 @@ PartitionInstallElToritoChildHandles (
} }
SubBlockSize = 512; SubBlockSize = 512;
SectorCount = Catalog->Boot.SectorCount; SectorCount = Catalog->Boot.SectorCount * (SIZE_2KB / Media->BlockSize);
switch (Catalog->Boot.MediaType) { switch (Catalog->Boot.MediaType) {
@ -236,7 +228,7 @@ PartitionInstallElToritoChildHandles (
CdDev.BootEntry = (UINT32) BootEntry; CdDev.BootEntry = (UINT32) BootEntry;
BootEntry++; BootEntry++;
CdDev.PartitionStart = Catalog->Boot.Lba; CdDev.PartitionStart = Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize);
if (SectorCount < 2) { if (SectorCount < 2) {
// //
// When the SectorCount < 2, set the Partition as the whole CD. // When the SectorCount < 2, set the Partition as the whole CD.
@ -265,8 +257,8 @@ PartitionInstallElToritoChildHandles (
BlockIo2, BlockIo2,
DevicePath, DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &CdDev, (EFI_DEVICE_PATH_PROTOCOL *) &CdDev,
Catalog->Boot.Lba, Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize),
Catalog->Boot.Lba + CdDev.PartitionSize - 1, (Catalog->Boot.Lba + CdDev.PartitionSize - 1) * (SIZE_2KB / Media->BlockSize),
SubBlockSize, SubBlockSize,
FALSE FALSE
); );