继续跟着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