From 63947cc4d01f92209a92cbe3987f324a85a39034 Mon Sep 17 00:00:00 2001 From: andrewfish Date: Tue, 7 Jun 2011 02:28:08 +0000 Subject: [PATCH] InOsEmuPkg: Fixed mounting device nodes and .dmg files in the emulator. There is some Linux specific code for mounting device nodes that needs to be tested. It may not compile! Singed-off-by: andrewfish git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11754 6f19259b-4bc3-4df7-8a09-765794883524 --- InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c | 2 +- InOsEmuPkg/InOsEmuPkg.dec | 11 ++- InOsEmuPkg/Unix/Sec/BlockIo.c | 99 ++++++++++++++++----------- InOsEmuPkg/Unix/Sec/SecMain.h | 3 + 4 files changed, 71 insertions(+), 44 deletions(-) diff --git a/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c b/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c index 9f3aa28b9e..8efc7b10e5 100644 --- a/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c +++ b/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c @@ -554,7 +554,7 @@ EmuBlockIoDriverBindingStart ( Private->BlockIo2.Reset = EmuBlockIo2Reset; Private->BlockIo2.ReadBlocksEx = EmuBlockIo2ReadBlocksEx; Private->BlockIo2.WriteBlocksEx = EmuBlockIo2WriteBlocksEx; - Private->BlockIo2.FlushBlocksEx = (EFI_BLOCK_FLUSH_EX)EmuBlockIoFlushBlocks; + Private->BlockIo2.FlushBlocksEx = EmuBlockIo2Flush; Private->ControllerNameTable = NULL; diff --git a/InOsEmuPkg/InOsEmuPkg.dec b/InOsEmuPkg/InOsEmuPkg.dec index 7cbed7f573..9660939d57 100644 --- a/InOsEmuPkg/InOsEmuPkg.dec +++ b/InOsEmuPkg/InOsEmuPkg.dec @@ -71,9 +71,16 @@ gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"..\\Fv\\Fv_Recovery.fd"|VOID*|0x00001009 gInOsEmuPkgTokenSpaceGuid.PcdEmuMemorySize|L"64!64"|VOID*|0x0000100c - - gInOsEmuPkgTokenSpaceGuid.PcdEmuPhysicalDisk|L"E:RW;245760;512"|VOID*|0x00001000 + # + # filename[:][R|F][O|W] + # filename can be a device node, like /dev/disk1 + # R - Removable Media F - Fixed Media + # O - Write protected W - Writable + # Default is Fixed Media, Writable + # Size comes from file or device. + # On Mac OS X you can use Disk Utility to create .dmg files and mount then like disks gInOsEmuPkgTokenSpaceGuid.PcdEmuVirtualDisk|L"FW;40960;512"|VOID*|0x00001001 + gInOsEmuPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window"|VOID*|0x00001018 gInOsEmuPkgTokenSpaceGuid.PcdEmuFileSystem|L".!../../../../../EdkShellBinPkg/bin/ia32/Apps"|VOID*|0x00001004 gInOsEmuPkgTokenSpaceGuid.PcdEmuSerialPort|L"/dev/ttyS0"|VOID*|0x00001002 diff --git a/InOsEmuPkg/Unix/Sec/BlockIo.c b/InOsEmuPkg/Unix/Sec/BlockIo.c index 1636d9508c..64494fe83f 100644 --- a/InOsEmuPkg/Unix/Sec/BlockIo.c +++ b/InOsEmuPkg/Unix/Sec/BlockIo.c @@ -30,9 +30,7 @@ typedef struct { BOOLEAN RemovableMedia; BOOLEAN WriteProtected; - UINTN BlockSize; UINT64 NumberOfBlocks; - UINT64 LastBlock; EMU_BLOCK_IO_PROTOCOL EmuBlockIo; EFI_BLOCK_IO_MEDIA *Media; @@ -66,12 +64,13 @@ SetFilePointer64 ( { EFI_STATUS Status; off_t res; + off_t offset = DistanceToMove; Status = EFI_SUCCESS; - res = lseek (Private->fd, DistanceToMove, MoveMethod); + res = lseek (Private->fd, offset, (int)MoveMethod); if (res == -1) { Status = EFI_INVALID_PARAMETER; - } + } if (NewFilePointer != NULL) { *NewFilePointer = res; @@ -88,7 +87,7 @@ EmuBlockIoOpenDevice ( { EFI_STATUS Status; UINT64 FileSize; - UINT64 EndOfFile; + struct statfs buf; // @@ -103,9 +102,9 @@ EmuBlockIoOpenDevice ( // Private->fd = open (Private->Filename, Private->Mode, 0644); if (Private->fd < 0) { - DEBUG ((EFI_D_INFO, "EmuOpenBlock: Could not open %a\n", Private->Filename)); + printf ("EmuOpenBlock: Could not open %s: %s\n", Private->Filename, strerror(errno)); Private->Media->MediaPresent = FALSE; - Status = EFI_NO_MEDIA; + Status = EFI_NO_MEDIA; goto Done; } @@ -121,36 +120,54 @@ EmuBlockIoOpenDevice ( // Status = SetFilePointer64 (Private, 0, &FileSize, SEEK_END); if (EFI_ERROR (Status)) { - FileSize = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize); - DEBUG ((EFI_D_ERROR, "EmuOpenBlock: Could not get filesize of %a\n", Private->Filename)); + printf ("EmuOpenBlock: Could not get filesize of %s\n", Private->Filename); Status = EFI_UNSUPPORTED; goto Done; } - - if (Private->NumberOfBlocks == 0) { - Private->NumberOfBlocks = DivU64x32 (FileSize, Private->BlockSize); - Private->LastBlock = Private->NumberOfBlocks - 1; - Private->Media->LastBlock = Private->LastBlock; - } - - EndOfFile = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize); - - if (FileSize != EndOfFile) { - // - // file is not the proper size, change it - // - DEBUG ((EFI_D_INIT, "EmuOpenBlock: Initializing block device: %a\n", Private->Filename)); - - // - // first set it to 0 - // - ftruncate (Private->fd, 0); - + + if (FileSize == 0) { + // lseek fails on a real device. ioctl calls are OS specific +#if __APPLE__ + { + UINT32 BlockSize; + + if (ioctl (Private->fd, DKIOCGETBLOCKSIZE, &BlockSize) == 0) { + Private->Media->BlockSize = BlockSize; + } + if (ioctl (Private->fd, DKIOCGETBLOCKCOUNT, &Private->NumberOfBlocks) == 0) { + if ((Private->NumberOfBlocks == 0) && (BlockSize == 0x800)) { + // A DVD is ~ 4.37 GB so make up a number + Private->Media->LastBlock = (0x100000000ULL/0x800) - 1; + } else { + Private->Media->LastBlock = Private->NumberOfBlocks - 1; + } + } + ioctl (Private->fd, DKIOCGETMAXBLOCKCOUNTWRITE, &Private->Media->OptimalTransferLengthGranularity); + } +#else + { + size_t BlockSize; + UINT64 DiskSize; + + if (ioctl (Private->fd, BLKSSZGET, &BlockSize) == 0) { + Private->Media->BlockSize = BlockSize; + } + if (ioctl (Private->fd, BLKGETSIZE64, &DiskSize) == 0) { + Private->NumberOfBlocks = DivU64x32 (DiskSize, (UINT32)BlockSize); + Private->Media->LastBlock = Private->NumberOfBlocks - 1; + } + } +#endif + + } else if (fstatfs (Private->fd, &buf) == 0) { // - // then set it to the needed file size (OS will zero fill it) + // Works for files, not devices // - ftruncate (Private->fd, EndOfFile); - } + Private->Media->BlockSize = buf.f_bsize; + Private->Media->OptimalTransferLengthGranularity = buf.f_iosize/buf.f_bsize; + Private->NumberOfBlocks = DivU64x32 (FileSize, Private->Media->BlockSize); + Private->Media->LastBlock = Private->NumberOfBlocks - 1; + } DEBUG ((EFI_D_INIT, "%HEmuOpenBlock: opened %a%N\n", Private->Filename)); Status = EFI_SUCCESS; @@ -185,19 +202,20 @@ EmuBlockIoCreateMapping ( Media->LogicalPartition = FALSE; Media->ReadOnly = Private->WriteProtected; Media->WriteCaching = FALSE; - Media->BlockSize = Private->BlockSize; Media->IoAlign = 1; Media->LastBlock = 0; // Filled in by OpenDevice // EFI_BLOCK_IO_PROTOCOL_REVISION2 Media->LowestAlignedLba = 0; Media->LogicalBlocksPerPhysicalBlock = 0; - + + // EFI_BLOCK_IO_PROTOCOL_REVISION3 Media->OptimalTransferLengthGranularity = 0; - + Status = EmuBlockIoOpenDevice (Private); + return Status; } @@ -293,7 +311,7 @@ EmuBlockIoReadWriteCommon ( // // Verify buffer size // - BlockSize = Private->BlockSize; + BlockSize = Private->Media->BlockSize; if (BufferSize == 0) { DEBUG ((EFI_D_INIT, "%s: Zero length read\n", CallerName)); return EFI_SUCCESS; @@ -305,7 +323,7 @@ EmuBlockIoReadWriteCommon ( } LastBlock = Lba + (BufferSize / BlockSize) - 1; - if (LastBlock > Private->LastBlock) { + if (LastBlock > Private->Media->LastBlock) { DEBUG ((EFI_D_INIT, "ReadBlocks: Attempted to read off end of device\n")); return EFI_INVALID_PARAMETER; } @@ -512,14 +530,15 @@ EmuBlockIoFlushBlocks ( ) { EMU_BLOCK_IO_PRIVATE *Private; + int Res; Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); if (Private->fd >= 0) { - close (Private->fd); - Private->fd = open (Private->Filename, Private->Mode, 0644); + Res = fcntl (Private->fd, F_FULLFSYNC); } + if (Token != NULL) { if (Token->Event != NULL) { // Caller is responcible for signaling EFI Event @@ -658,8 +677,6 @@ EmuBlockIoThunkOpen ( } } - Private->BlockSize = 512; - This->Interface = &Private->EmuBlockIo; This->Private = Private; return EFI_SUCCESS; diff --git a/InOsEmuPkg/Unix/Sec/SecMain.h b/InOsEmuPkg/Unix/Sec/SecMain.h index f2487b9133..d660058586 100644 --- a/InOsEmuPkg/Unix/Sec/SecMain.h +++ b/InOsEmuPkg/Unix/Sec/SecMain.h @@ -78,6 +78,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include @@ -90,6 +91,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #define _XOPEN_SOURCE #ifndef _Bool #define _Bool char // for clang debug @@ -97,6 +99,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #else #include #include +#include #endif #include -- 2.39.2