Step to UEFI (254)PlatformPei 分析

继续跟着Log 分析,加载了PlatformPei.efi,它代码位于 \OvmfPkg\PlatformPei 目录中。

Loading PEIM 222C386D-5ABC-4FB4-B124-FBB82488ACF4
Loading PEIM at 0x00000851920 EntryPoint=0x00000851F70 PlatformPei.efi

从Log 中可以看到,刚进入这个 Module 之后,调用到位于\OvmfPkg\Library\QemuFwCfgLib\QemuFwCfgPei.c 的QemuFwCfgInitialize() 函数中。QemuFwCfgPeiLib.inf 中指定了这个函数作为这个 PEIM 的构造函数。

  CONSTRUCTOR                    = QemuFwCfgInitialize

接下来的 Log 是:

Select Item: 0x0
FW CFG Signature: 0x554D4551
Select Item: 0x1
FW CFG Revision: 0x3
QemuFwCfg interface (DMA) is supported.

对应 \OvmfPkg\PlatformPei\Platform.c 中的如下函数:

/**
  Perform Platform PEI initialization.

  @param  FileHandle      Handle of the file being invoked.
  @param  PeiServices     Describes the list of possible PEI Services.

  @return EFI_SUCCESS     The PEIM initialized successfully.

**/
EFI_STATUS
EFIAPI
InitializePlatform (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
Platform PEIM Loaded
CMOS:
00: 44 00 54 00 06 00 02 13 12 21 26 02 10 80 00 00
10: 50 00 00 00 07 80 02 FF FF 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: FF FF 20 00 00 07 00 20 30 00 00 00 00 12 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

这里会调用到\OvmfPkg\Library\QemuFwCfgS3Lib\QemuFwCfgS3PeiDxe.c中的QemuFwCfgS3Enabled()

/**
  Determine if S3 support is explicitly enabled.

  @retval  TRUE   If S3 support is explicitly enabled. Other functions in this
                  library may be called (subject to their individual
                  restrictions).

           FALSE  Otherwise. This includes unavailability of the firmware
                  configuration interface. No other function in this library
                  must be called.
**/
BOOLEAN
EFIAPI
QemuFwCfgS3Enabled (
  VOID
  ) 

QEMU 模拟了 SPI ROM,使得BIOS能够访问到一些设置。

Select Item: 0x19
Select Item: 0x27
S3 support was detected on QEMU
  if (QemuFwCfgS3Enabled ()) {
    DEBUG ((DEBUG_INFO, "S3 support was detected on QEMU\n"));
    mS3Supported = TRUE;
    Status = PcdSetBoolS (PcdAcpiS3Enable, TRUE);
    ASSERT_EFI_ERROR (Status);
  }
Install PPI: 7408D748-FC8C-4EE6-9288-C4BEC092A410

BootModeInitialization() 中的Status = PeiServicesInstallPpi (mPpiBootMode); 输出

Select Item: 0x19
Select Item: 0x25
ScanOrAdd64BitE820Ram: Base=0x0 Length=0x8000000 Type=1
Select Item: 0x19
Select Item: 0x19
GetFirstNonAddress: Pci64Base=0x800000000 Pci64Size=0x800000000
Select Item: 0x5

对应代码在 \ovmfpkg\platformpei\MemDetect.c

/**
  Iterate over the RAM entries in QEMU's fw_cfg E820 RAM map that start outside
  of the 32-bit address range.

  Find the highest exclusive >=4GB RAM address, or produce memory resource
  descriptor HOBs for RAM entries that start at or above 4GB.

  @param[out] MaxAddress  If MaxAddress is NULL, then ScanOrAdd64BitE820Ram()
                          produces memory resource descriptor HOBs for RAM
                          entries that start at or above 4GB.

                          Otherwise, MaxAddress holds the highest exclusive
                          >=4GB RAM address on output. If QEMU's fw_cfg E820
                          RAM map contains no RAM entry that starts outside of
                          the 32-bit address range, then MaxAddress is exactly
                          4GB on output.

  @retval EFI_SUCCESS         The fw_cfg E820 RAM map was found and processed.

  @retval EFI_PROTOCOL_ERROR  The RAM map was found, but its size wasn't a
                              whole multiple of sizeof(EFI_E820_ENTRY64). No
                              RAM entry was processed.

  @return                     Error codes from QemuFwCfgFindFile(). No RAM
                              entry was processed.
**/
STATIC
EFI_STATUS
ScanOrAdd64BitE820Ram (
  OUT UINT64 *MaxAddress OPTIONAL
  )
MaxCpuCountInitialization: CmdData2=0x0
MaxCpuCountInitialization: QEMU v2.7 reset bug: BootCpuCount=1 Present=0
MaxCpuCountInitialization: BootCpuCount=0 mMaxCpuCount=1

PublishPeiMemory: mPhysMemAddressWidth=36 PeiMemoryCap=65800 KB
PeiInstallPeiMemory MemoryBegin 0x3F36000, MemoryLength 0x4042000

QEMU 的内存初始化在  \ovmfpkg\platformpei\MemDetect.c

/**
  Publish PEI core memory

  @return EFI_SUCCESS     The PEIM initialized successfully.

**/
EFI_STATUS
PublishPeiMemory (
  VOID
  )
  PublishPeiMemory ();

QemuUc32BaseInitialization: rounded UC32 base from 0x8000000 up to 0x80000000, for an UC32 size of 0x80000000

VOID
QemuUc32BaseInitialization (
  VOID
  )
QemuInitializeRam called

具体实现在 \ovmfpkg\platformpei\MemDetect.c 文件中

/**
  Publish system RAM and reserve memory regions

**/
VOID
InitializeRamRegions (
  VOID
  )
QemuInitializeRam ();
/**
  Peform Memory Detection for QEMU / KVM

**/
STATIC
VOID
QemuInitializeRam (
  VOID
  )
Platform PEI Firmware Volume Initialization
Install PPI: 49EDB1C1-BF21-4761-BB12-EB0031AABB39
Notify: PPI Guid: 49EDB1C1-BF21-4761-BB12-EB0031AABB39, Peim notify entry point: 82153C
The 1th FV start address is 0x00000900000, size is 0x00C00000, handle is 0x900000
Select Item: 0x19
Register PPI Notify: EE16160A-E8BE-47A6-820A-C6900DB0250A
Select Item: 0x19
\MdePkg\MdePkg.dec
  ## Include/Ppi/MpServices.h
  gEfiPeiMpServicesPpiGuid           = { 0xee16160a, 0xe8be, 0x47a6, { 0x82, 0xa, 0xc6, 0x90, 0xd, 0xb0, 0x25, 0xa } }

PlatformPei.efi 中有大量和“硬件”相关的内容,最重要的部分是内存的初始化,运行完成后,内存可用。

参考:

1. https://www.lab-z.com/stu238/ OVMF 从第一条指令到 SecMain

发表评论

您的电子邮箱地址不会被公开。