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
This commit is contained in:
andrewfish
2011-06-07 02:28:08 +00:00
parent 63e78d5254
commit 63947cc4d0
4 changed files with 71 additions and 44 deletions

View File

@@ -554,7 +554,7 @@ EmuBlockIoDriverBindingStart (
Private->BlockIo2.Reset = EmuBlockIo2Reset; Private->BlockIo2.Reset = EmuBlockIo2Reset;
Private->BlockIo2.ReadBlocksEx = EmuBlockIo2ReadBlocksEx; Private->BlockIo2.ReadBlocksEx = EmuBlockIo2ReadBlocksEx;
Private->BlockIo2.WriteBlocksEx = EmuBlockIo2WriteBlocksEx; Private->BlockIo2.WriteBlocksEx = EmuBlockIo2WriteBlocksEx;
Private->BlockIo2.FlushBlocksEx = (EFI_BLOCK_FLUSH_EX)EmuBlockIoFlushBlocks; Private->BlockIo2.FlushBlocksEx = EmuBlockIo2Flush;
Private->ControllerNameTable = NULL; Private->ControllerNameTable = NULL;

View File

@@ -71,9 +71,16 @@
gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"..\\Fv\\Fv_Recovery.fd"|VOID*|0x00001009 gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"..\\Fv\\Fv_Recovery.fd"|VOID*|0x00001009
gInOsEmuPkgTokenSpaceGuid.PcdEmuMemorySize|L"64!64"|VOID*|0x0000100c 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.PcdEmuVirtualDisk|L"FW;40960;512"|VOID*|0x00001001
gInOsEmuPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window"|VOID*|0x00001018 gInOsEmuPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window"|VOID*|0x00001018
gInOsEmuPkgTokenSpaceGuid.PcdEmuFileSystem|L".!../../../../../EdkShellBinPkg/bin/ia32/Apps"|VOID*|0x00001004 gInOsEmuPkgTokenSpaceGuid.PcdEmuFileSystem|L".!../../../../../EdkShellBinPkg/bin/ia32/Apps"|VOID*|0x00001004
gInOsEmuPkgTokenSpaceGuid.PcdEmuSerialPort|L"/dev/ttyS0"|VOID*|0x00001002 gInOsEmuPkgTokenSpaceGuid.PcdEmuSerialPort|L"/dev/ttyS0"|VOID*|0x00001002

View File

@@ -30,9 +30,7 @@ typedef struct {
BOOLEAN RemovableMedia; BOOLEAN RemovableMedia;
BOOLEAN WriteProtected; BOOLEAN WriteProtected;
UINTN BlockSize;
UINT64 NumberOfBlocks; UINT64 NumberOfBlocks;
UINT64 LastBlock;
EMU_BLOCK_IO_PROTOCOL EmuBlockIo; EMU_BLOCK_IO_PROTOCOL EmuBlockIo;
EFI_BLOCK_IO_MEDIA *Media; EFI_BLOCK_IO_MEDIA *Media;
@@ -66,12 +64,13 @@ SetFilePointer64 (
{ {
EFI_STATUS Status; EFI_STATUS Status;
off_t res; off_t res;
off_t offset = DistanceToMove;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
res = lseek (Private->fd, DistanceToMove, MoveMethod); res = lseek (Private->fd, offset, (int)MoveMethod);
if (res == -1) { if (res == -1) {
Status = EFI_INVALID_PARAMETER; Status = EFI_INVALID_PARAMETER;
} }
if (NewFilePointer != NULL) { if (NewFilePointer != NULL) {
*NewFilePointer = res; *NewFilePointer = res;
@@ -88,7 +87,7 @@ EmuBlockIoOpenDevice (
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT64 FileSize; UINT64 FileSize;
UINT64 EndOfFile; struct statfs buf;
// //
@@ -103,9 +102,9 @@ EmuBlockIoOpenDevice (
// //
Private->fd = open (Private->Filename, Private->Mode, 0644); Private->fd = open (Private->Filename, Private->Mode, 0644);
if (Private->fd < 0) { 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; Private->Media->MediaPresent = FALSE;
Status = EFI_NO_MEDIA; Status = EFI_NO_MEDIA;
goto Done; goto Done;
} }
@@ -121,36 +120,54 @@ EmuBlockIoOpenDevice (
// //
Status = SetFilePointer64 (Private, 0, &FileSize, SEEK_END); Status = SetFilePointer64 (Private, 0, &FileSize, SEEK_END);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
FileSize = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize); printf ("EmuOpenBlock: Could not get filesize of %s\n", Private->Filename);
DEBUG ((EFI_D_ERROR, "EmuOpenBlock: Could not get filesize of %a\n", Private->Filename));
Status = EFI_UNSUPPORTED; Status = EFI_UNSUPPORTED;
goto Done; goto Done;
} }
if (Private->NumberOfBlocks == 0) { if (FileSize == 0) {
Private->NumberOfBlocks = DivU64x32 (FileSize, Private->BlockSize); // lseek fails on a real device. ioctl calls are OS specific
Private->LastBlock = Private->NumberOfBlocks - 1; #if __APPLE__
Private->Media->LastBlock = Private->LastBlock; {
} UINT32 BlockSize;
EndOfFile = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize); if (ioctl (Private->fd, DKIOCGETBLOCKSIZE, &BlockSize) == 0) {
Private->Media->BlockSize = BlockSize;
if (FileSize != EndOfFile) { }
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) {
// //
// file is not the proper size, change it // Works for files, not devices
// //
DEBUG ((EFI_D_INIT, "EmuOpenBlock: Initializing block device: %a\n", Private->Filename)); Private->Media->BlockSize = buf.f_bsize;
Private->Media->OptimalTransferLengthGranularity = buf.f_iosize/buf.f_bsize;
// Private->NumberOfBlocks = DivU64x32 (FileSize, Private->Media->BlockSize);
// first set it to 0 Private->Media->LastBlock = Private->NumberOfBlocks - 1;
// }
ftruncate (Private->fd, 0);
//
// then set it to the needed file size (OS will zero fill it)
//
ftruncate (Private->fd, EndOfFile);
}
DEBUG ((EFI_D_INIT, "%HEmuOpenBlock: opened %a%N\n", Private->Filename)); DEBUG ((EFI_D_INIT, "%HEmuOpenBlock: opened %a%N\n", Private->Filename));
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@@ -185,19 +202,20 @@ EmuBlockIoCreateMapping (
Media->LogicalPartition = FALSE; Media->LogicalPartition = FALSE;
Media->ReadOnly = Private->WriteProtected; Media->ReadOnly = Private->WriteProtected;
Media->WriteCaching = FALSE; Media->WriteCaching = FALSE;
Media->BlockSize = Private->BlockSize;
Media->IoAlign = 1; Media->IoAlign = 1;
Media->LastBlock = 0; // Filled in by OpenDevice Media->LastBlock = 0; // Filled in by OpenDevice
// EFI_BLOCK_IO_PROTOCOL_REVISION2 // EFI_BLOCK_IO_PROTOCOL_REVISION2
Media->LowestAlignedLba = 0; Media->LowestAlignedLba = 0;
Media->LogicalBlocksPerPhysicalBlock = 0; Media->LogicalBlocksPerPhysicalBlock = 0;
// EFI_BLOCK_IO_PROTOCOL_REVISION3 // EFI_BLOCK_IO_PROTOCOL_REVISION3
Media->OptimalTransferLengthGranularity = 0; Media->OptimalTransferLengthGranularity = 0;
Status = EmuBlockIoOpenDevice (Private); Status = EmuBlockIoOpenDevice (Private);
return Status; return Status;
} }
@@ -293,7 +311,7 @@ EmuBlockIoReadWriteCommon (
// //
// Verify buffer size // Verify buffer size
// //
BlockSize = Private->BlockSize; BlockSize = Private->Media->BlockSize;
if (BufferSize == 0) { if (BufferSize == 0) {
DEBUG ((EFI_D_INIT, "%s: Zero length read\n", CallerName)); DEBUG ((EFI_D_INIT, "%s: Zero length read\n", CallerName));
return EFI_SUCCESS; return EFI_SUCCESS;
@@ -305,7 +323,7 @@ EmuBlockIoReadWriteCommon (
} }
LastBlock = Lba + (BufferSize / BlockSize) - 1; 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")); DEBUG ((EFI_D_INIT, "ReadBlocks: Attempted to read off end of device\n"));
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
@@ -512,14 +530,15 @@ EmuBlockIoFlushBlocks (
) )
{ {
EMU_BLOCK_IO_PRIVATE *Private; EMU_BLOCK_IO_PRIVATE *Private;
int Res;
Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);
if (Private->fd >= 0) { if (Private->fd >= 0) {
close (Private->fd); Res = fcntl (Private->fd, F_FULLFSYNC);
Private->fd = open (Private->Filename, Private->Mode, 0644);
} }
if (Token != NULL) { if (Token != NULL) {
if (Token->Event != NULL) { if (Token->Event != NULL) {
// Caller is responcible for signaling EFI Event // Caller is responcible for signaling EFI Event
@@ -658,8 +677,6 @@ EmuBlockIoThunkOpen (
} }
} }
Private->BlockSize = 512;
This->Interface = &Private->EmuBlockIo; This->Interface = &Private->EmuBlockIo;
This->Private = Private; This->Private = Private;
return EFI_SUCCESS; return EFI_SUCCESS;

View File

@@ -78,6 +78,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/statvfs.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h> #include <netdb.h>
@@ -90,6 +91,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <net/bpf.h> #include <net/bpf.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/disk.h>
#define _XOPEN_SOURCE #define _XOPEN_SOURCE
#ifndef _Bool #ifndef _Bool
#define _Bool char // for clang debug #define _Bool char // for clang debug
@@ -97,6 +99,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#else #else
#include <termio.h> #include <termio.h>
#include <sys/vfs.h> #include <sys/vfs.h>
#include <linux/fs.h>
#endif #endif
#include <utime.h> #include <utime.h>