Re: [edk2] OVMF on QEMU with recent EDK2 code

Subject: Re: [edk2] OVMF on QEMU with recent EDK2 code

From: Bill Paul <wpaul@windriver.com>

To: Laszlo Ersek <lersek@redhat.com>

Date: 2014-01-28 18:28:43

Of all the gin joints in all the towns in all the world, Laszlo Ersek had to 
walk into mine at 04:07:29 on Tuesday 28 January 2014 and say:

> On 01/27/14 23:01, Bill Paul wrote:
> > Hello all:
> > 
> > I have some questions related to what I think is a recent change in the
> > OVMF code.
> > 
> > I checked out the EDK2 code to build a set of OVMF images for use with
> > QEMU. I'm using QEMU 1.1.1 on FreeBSD/amd64 9.1-RELEASE.
> > 
> > When I did the svn checkout, I got revision 15189.
> > 
> > I was able to build the firmware for both IA32 and X64 (after first
> > setting up the cross-compiler environment with mingw-gcc-build.py and
> > building the BaseTools for FreeBSD). I used the general UNIX-based
> > instructions, and for the most part, building OVMF on FreeBSD is pretty
> > painless. (The only real nit is that
> > edk2/BaseTools/Source/C/GenFv/GenFvInternalLib.c wants ,
> > but on FreeBSD it's just . Everything else works just like it
> > says on the box.)
> > 
> > I added the openssl patch to the CryptoPkg patch and built with the
> > following commands:
> > 
> > build -a X64 -p OvmfPkg/OvmfPkgX64.dsc \
> > 
> > 	-DFD_SIZE_2MB -DSECURE_BOOT_ENABLE=TRUE
> > 
> > build -a IA32 -p OvmfPkg/OvmfPkgIa32.dsc \
> > 
> > 	-DFD_SIZE_2MB -DSECURE_BOOT_ENABLE=TRUE
> > 
> > The resulting OVMF images boot up and run with QEMU just fine, however I
> > noticed one major difference in behavior compared to the images that I
> > built the last time around (which was back in April/May of last year).
> > 
> > The difference is in the memory map. There is a large (2MB) block at
> > address 0x820000 marked as ACPI NVS. Below is the output from memmap run
> > from the shell that shows this (this is with a simulation using
> > qemu-system-x86-64 using 2GB of RAM):
> > 
> > [...]
> > Shell> memmap -b
> > Type      Start            End              #pages             Attributes
> > Available 0000000000000000-000000000009FFFF 00000000000000A0
> > 000000000000000F Available 0000000000100000-000000000081FFFF
> > 0000000000000720 000000000000000F ACPI_NVS 
> > 0000000000820000-00000000008FFFFF 00000000000000E0 000000000000000F
> > BS_Data   0000000000900000-0000000000FFFFFF 0000000000000700
> > 000000000000000F Available 0000000001000000-000000007BFFFFFF
> > 000000000007B000 000000000000000F BS_Data  
> > 000000007C000000-000000007C01FFFF 0000000000000020 000000000000000F
> > Available 000000007C020000-000000007E32EFFF 000000000000230F
> > 000000000000000F BS_Data   000000007E32F000-000000007E353FFF
> > 0000000000000025 000000000000000F Available
> > 000000007E354000-000000007E364FFF 0000000000000011 000000000000000F
> > BS_Data   000000007E365000-000000007E49AFFF 0000000000000136
> > 000000000000000F LoaderCode 000000007E49B000-000000007E56EFFF
> > 00000000000000D4 000000000000000F BS_Data  
> > 000000007E56F000-000000007EA29FFF 00000000000004BB 000000000000000F
> > BS_Code   000000007EA2A000-000000007EC0BFFF 00000000000001E2
> > 000000000000000F RT_Data   000000007EC0C000-000000007ECBEFFF
> > 00000000000000B3 800000000000000F RT_Code  
> > 000000007ECBF000-000000007ED51FFF 0000000000000093 800000000000000F
> > BS_Data   000000007ED52000-000000007FD51FFF 0000000000001000
> > 000000000000000F Available 000000007FD52000-000000007FD53FFF
> > 0000000000000002 000000000000000F BS_Code  
> > 000000007FD54000-000000007FED1FFF 000000000000017E 000000000000000F
> > RT_Code   000000007FED2000-000000007FF01FFF 0000000000000030
> > 800000000000000F RT_Data   000000007FF02000-000000007FF25FFF
> > 0000000000000024 800000000000000F Reserved 
> > 000000007FF26000-000000007FF29FFF 0000000000000004 000000000000000F
> > ACPIRec   000000007FF2A000-000000007FF31FFF 0000000000000008
> > 000000000000000F ACPI_NVS  000000007FF32000-000000007FF35FFF
> > 0000000000000004 000000000000000F BS_Data  
> > 000000007FF36000-000000007FFCFFFF 000000000000009A 000000000000000F
> > RT_Data   000000007FFD0000-000000007FFFFFFF 0000000000000030
> > 800000000000000F RT_Data   00000000FFE00000-00000000FFFFFFFF
> > 0000000000000200 8000000000000001
> > 
> >   Reserved  :          4 Pages (16,384)
> >   LoaderCode:        212 Pages (868,352)
> >   LoaderData:          0 Pages (0)
> >   BS_Code   :        864 Pages (3,538,944)
> >   BS_Data   :      7,632 Pages (31,260,672)
> >   RT_Code   :        195 Pages (798,720)
> >   RT_Data   :        775 Pages (3,174,400)
> >   ACPI Recl :          8 Pages (32,768)
> >   ACPI NVS  :        228 Pages (933,888)
> >   MMIO      :          0 Pages (0)
> >   Available :    514,786 Pages (2,108,563,456)
> > 
> > Total Memory: 2049 MB (2,149,187,584 Bytes)
> > [...]
> > 
> > After some investigation, I found that this has to do with the following
> > code in OvmfPkg/PlatformPei/Fv.c:
> > 
> > [...]
> > 
> >   DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n"));
> >   
> >   //
> >   // Create a memory allocation HOB for the PEI FV.
> >   //
> >   // This is marked as ACPI NVS so it will still be available on S3
> >   resume. //
> >   BuildMemoryAllocationHob (
> >   
> >     PcdGet32 (PcdOvmfPeiMemFvBase),
> >     PcdGet32 (PcdOvmfPeiMemFvSize),
> >     EfiACPIMemoryNVS
> >     );
> > 
> > [...]
> > 
> > The PeiFv address is set to 0x800000 in OvmfPkgX64.fdf and
> > OvmfPkgIa32.fdf:
> > 
> > [...]
> > [FD.MEMFD]
> > BaseAddress   = 0x800000
> > Size          = 0x800000
> > ErasePolarity = 1
> > BlockSize     = 0x10000
> > NumBlocks     = 0x80
> > 
> > 0x000000|0x006000
> > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|
> > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
> > 
> > 0x010000|0x008000
> > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|
> > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
> > 
> > 0x020000|0x0E0000
> > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|
> > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
> > FV = PEIFV
> > 
> > 0x100000|0x700000
> > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|
> > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
> > FV = DXEFV
> > [...]
> > 
> > My questions are:
> > 
> > - What exactly is this block for? It's not clear to me what the PEI
> > module does, though it seems to have something to do with bootstrapping
> > the firmware out of the flash region. Once the firmware is up and
> > running, does this really need to be preserved?
> 
> It must be preserved.
> 
> Jordan is in the middle of adding S3 suspend/resume support to OVMF. The
> most recent posted version was
> 
>   [edk2] [PATCH v4 00/26] S3 suspend/resume for OVMF
> 
> The first eight patches have been pushed (ending at SVN r15151), and
> that's what you're seeing. It's not a bug, it's just that the actual use
> case for this code is not visible in the tree yet.
> 
> The use case is (going to be): at S3 resume, the VM is actually re-set,
> and the firmware starts to run from the beginning. It has to overwrite
> some RAM areas unconditionally to be able to run, and it needs some RAM
> areas to stay intact from the time of the very first cold boot.
> 
> The area you've identified belongs to the second category. It contains a
> firmware volume that holds the various PEI modules that must run at both
> normal startup and at S3 resume. The OS must not trample over this area
> during runtime because the modules will be needed after you suspend and
> wake the VM. The OS is instructed to stay away by marking the area in
> the memory map as ACPI NVS.
> 
> > - If it must be preserved, is there any way to move this to some other
> > location in RAM? (I tried fiddling with the BaseAddress value in the .fdf
> > files, and that helps, but that's not really a portable solution.
> > 
> > It happens that, at least for me, this block creates a memory hole in the
> > worst possible location. I can work around the problem a bit by changing
> > the BaseAddress shown above to a location a bit higher up in RAM, but
> > something tells me there's got to be a better way.
> 
> Placing this string of areas at 0x800000 is quite arbitrary for us, as
> far as I know. I believe (without doing any investigation) that we could
> move it a bit around, but it must stay low. The decompression happens at
> an early stage.

Can't you move it after decompression?

> Why does it bother you where it is right now? What conflict do you see?

What I'm doing is running VxWorks in QEMU for testing purposes. Using QEMU and 
OVMF has proven to be an excellent way to experiment with booting VxWorks with 
UEFI before moving to real hardware.

The problem I'm having has to do with VxWorks' memory management. Due to 
hysterical raisins, when the VxWorks kernel starts up, it expects to be given 
a contiguous chunk of memory to use as its initial heap memory pool. Once the 
kernel is running you can add additional chunks -- these are called memory 
partitions by the memory manager.

The thing is, on the Intel arch, it's always been assumed that that the first 
chunk of usable memory starts at 0x100000 and is fairly large. With the memory 
hole created by the PEIFV block, you end up with only about 7MB in this block, 
which is too small. (The real havoc occurs with 64-bit VxWorks, which has 
additional restrictions.)

It is possible to tweak things in VxWorks to avoid this problem, but it's a 
pain. It's also not something we typically encounter on real hardware.

> Additionally, after the full S3 support series committed, further code
> will be added to honor the case when the user disables S3 on the qemu
> command line ("-global PIIX4_PM.disable_s3=1"). Then the memory
> allocation in question will be qualified as Boot Services Data (rather
> than ACPI NVS), and the OS will be able to drop it after transitioning
> to runtime.

It appears I need a newer version of QEMU for that option:

root@core:/home/wpaul/ovmf # qemu-system-x86_64 -global PIIX4_PM.disable_s3=1
qemu-system-x86_64: Property '.disable_s3' not found

That aside, this would be an acceptable compromise, at least until VxWorks 
supports S3 resume on the Intel architecture. :)

I still think the placement of the PEIFV block is much less than ideal, but 
for the time being I can deal with it.

-Bill

> Laszlo

-- 
=============================================================================
-Bill Paul            (510) 749-2329 | Senior Member of Technical Staff,
                 wpaul@windriver.com | Master of Unix-Fu - Wind River Systems
=============================================================================
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=============================================================================

------------------------------------------------------------------------------
WatchGuard Dimension instantly turns raw network data into actionable 
security intelligence. It gives you real-time visual feedback on key
security issues and trends.  Skip the complicated setup - simply import
a virtual appliance and go from zero to informed in seconds.
http://pubads.g.doubleclick.net/gampad/clk?id=123612991&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel