From 8052c4a2b9e0c3575e912e5867cd0d7c2669c925 Mon Sep 17 00:00:00 2001 From: andrewfish Date: Wed, 8 Jun 2011 04:32:18 +0000 Subject: [PATCH] Update the FD mapping so the volatile areas write back to the FD file. Currently they are only mapped as a memory copy of the file. This also make FV read only. The current scheme maps a file into a memory buffer. You can write to the memory buffer, but if you restart the emulator the data is not written back to the FD. Since the build, rebuilds the FD it will blow away any changes. You can now set variables and restart the emulator and they are still set. There is a bug if the FV is set to write protect that still needs to be tracked down. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11761 6f19259b-4bc3-4df7-8a09-765794883524 --- InOsEmuPkg/Unix/Sec/SecMain.c | 87 ++++++++++++++++++++++++++++----- InOsEmuPkg/Unix/Sec/SecMain.h | 7 +++ InOsEmuPkg/Unix/Sec/SecMain.inf | 12 +++++ 3 files changed, 95 insertions(+), 11 deletions(-) diff --git a/InOsEmuPkg/Unix/Sec/SecMain.c b/InOsEmuPkg/Unix/Sec/SecMain.c index 41b66b3bc0..1771f36132 100644 --- a/InOsEmuPkg/Unix/Sec/SecMain.c +++ b/InOsEmuPkg/Unix/Sec/SecMain.c @@ -212,14 +212,24 @@ main ( } FileName[Index1] = '\0'; - // - // Open the FD and remmeber where it got mapped into our processes address space - // - Status = MapFile ( - FileName, - &gFdInfo[Index].Address, - &gFdInfo[Index].Size - ); + if (Index == 0) { + // Map FV Recovery Read Only and other areas Read/Write + Status = MapFd0 ( + FileName, + &gFdInfo[0].Address, + &gFdInfo[0].Size + ); + } else { + // + // Open the FD and remmeber where it got mapped into our processes address space + // Maps Read Only + // + Status = MapFile ( + FileName, + &gFdInfo[Index].Address, + &gFdInfo[Index].Size + ); + } if (EFI_ERROR (Status)) { printf ("ERROR : Can not open Firmware Device File %s (%x). Exiting.\n", FileName, (unsigned int)Status); exit (1); @@ -350,7 +360,7 @@ MapFile ( OUT UINT64 *Length ) { - int fd; + int fd; VOID *res; UINTN FileSize; @@ -361,7 +371,7 @@ MapFile ( FileSize = lseek (fd, 0, SEEK_END); - res = MapMemory (fd, FileSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED); + res = MapMemory (fd, FileSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE); close (fd); @@ -369,13 +379,68 @@ MapFile ( perror ("MapFile() Failed"); return EFI_DEVICE_ERROR; } - + *Length = (UINT64) FileSize; *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res; return EFI_SUCCESS; } +EFI_STATUS +MapFd0 ( + IN CHAR8 *FileName, + IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, + OUT UINT64 *Length + ) +{ + int fd; + VOID *res, *res2; + UINTN FileSize; + UINTN FvSize; + + fd = open (FileName, O_RDWR); + if (fd < 0) { + return EFI_NOT_FOUND; + } + FileSize = lseek (fd, 0, SEEK_END); + + FvSize = FixedPcdGet64 (PcdEmuFlashFvRecoverySize); + + // Assume start of FD is Recovery FV, and make it write protected + res = mmap ( + (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase), + FvSize, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE, + fd, + 0 + ); + if (res == MAP_FAILED) { + perror ("MapFile() Failed res ="); + close (fd); + return EFI_DEVICE_ERROR; + } + + // Map the rest of the FD as read/write + res2 = mmap ( + (void *)(FixedPcdGet64 (PcdEmuFlashFvRecoveryBase) + FvSize), + FileSize - FvSize, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_SHARED, + fd, + FvSize + ); + close (fd); + if (res2 == MAP_FAILED) { + perror ("MapFile() Failed res2 ="); + return EFI_DEVICE_ERROR; + } + + *Length = (UINT64) FileSize; + *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res; + + return EFI_SUCCESS; +} /*++ diff --git a/InOsEmuPkg/Unix/Sec/SecMain.h b/InOsEmuPkg/Unix/Sec/SecMain.h index d660058586..af88d06837 100644 --- a/InOsEmuPkg/Unix/Sec/SecMain.h +++ b/InOsEmuPkg/Unix/Sec/SecMain.h @@ -310,6 +310,13 @@ MapFile ( OUT UINT64 *Length ); +EFI_STATUS +MapFd0 ( + IN CHAR8 *FileName, + IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, + OUT UINT64 *Length + ); + VOID SecSleep (UINT64 Milliseconds); diff --git a/InOsEmuPkg/Unix/Sec/SecMain.inf b/InOsEmuPkg/Unix/Sec/SecMain.inf index 4d3c28b8ea..0e494e76bb 100644 --- a/InOsEmuPkg/Unix/Sec/SecMain.inf +++ b/InOsEmuPkg/Unix/Sec/SecMain.inf @@ -91,6 +91,18 @@ gInOsEmuPkgTokenSpaceGuid.PcdEmuSerialPort gInOsEmuPkgTokenSpaceGuid.PcdEmuNetworkInterface + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashFvRecoveryBase + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashFvRecoverySize + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogBase + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + + [BuildOptions] GCC:*_*_IA32_DLINK_FLAGS == -o $(BIN_DIR)/SecMain -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o -L/usr/X11R6/lib -lXext -lX11 /usr/lib/crtn.o -- 2.39.2