Step to UEFI (255)PlatformPei之后

当BIOS执行完 PlatformPei.efi 之后,不会和其他PeiM 一样继续执行而是要进行一些特别的处理。

在\MdeModulePkg\Core\Pei\Dispatcher\Dispatcher.c 文件 PeiDispatcher函数中会 invoke 每一个PEIM。

/**
  Conduct PEIM dispatch.

  @param SecCoreData     Points to a data structure containing information about the PEI core's operating
                         environment, such as the size and location of temporary RAM, the stack location and
                         the BFV location.
  @param Private         Pointer to the private data passed in from caller

**/
VOID
PeiDispatcher (
  IN CONST EFI_SEC_PEI_HAND_OFF  *SecCoreData,
  IN PEI_CORE_INSTANCE           *Private
  )

这里会调用每个 PEIM 的 EntryPoint, 有兴趣的朋友可以在此加入 Debug Message.

                  //
                  // Call the PEIM entry point for PEIM driver
                  //
                  PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
                  PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);
                  Private->PeimDispatchOnThisPass = TRUE;

特别提一句,在\mdemodulepkg\core\pei\dispatcher\Dispatcher.c这个文件中,大多数 DEBUG message是通过下面的方式输出的:

DEBUG ((DEBUG_DISPATCH, "Evaluate PEI DEPEX for FFS(Unknown)\n"));

但是如果你也用这种方式,会发现无法在Log 文件中看到消息的。这是因为在\OvmfPkg\OvmfPkgX64.dsc 中定义如下:

  # DEBUG_INIT      0x00000001  // Initialization
  # DEBUG_WARN      0x00000002  // Warnings
  # DEBUG_LOAD      0x00000004  // Load events
  # DEBUG_FS        0x00000008  // EFI File system
  # DEBUG_POOL      0x00000010  // Alloc & Free (pool)
  # DEBUG_PAGE      0x00000020  // Alloc & Free (page)
  # DEBUG_INFO      0x00000040  // Informational debug messages
  # DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
  # DEBUG_VARIABLE  0x00000100  // Variable
  # DEBUG_BM        0x00000400  // Boot Manager
  # DEBUG_BLKIO     0x00001000  // BlkIo Driver
  # DEBUG_NET       0x00004000  // SNP Driver
  # DEBUG_UNDI      0x00010000  // UNDI Driver
  # DEBUG_LOADFILE  0x00020000  // LoadFile
  # DEBUG_EVENT     0x00080000  // Event messages
  # DEBUG_GCD       0x00100000  // Global Coherency Database changes
  # DEBUG_CACHE     0x00200000  // Memory range cachability changes
  # DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
  #                             // significantly impact boot performance
  # DEBUG_ERROR     0x80000000  // Error
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F

默认是没有DEBUG_DISPATCH  的,所以要么将 PcdDebugPrintErrorLevel 设置为0x800000CF,要么在 DEBUG 宏中使用DEBUG_INFO参数。

从PlatformPei.efi出来之后,因为内存初始化已完成,进入下面的函数之后 PeiCheckAndSwitchStack (SecCoreData, Private);会检查

Private->SwitchStackSignal是否已经Enable。 具体的是在\mdemodulepkg\core\pei\memory\MemoryServices.c 代码中设置起来的。

/**

  This function registers the found memory configuration with the PEI Foundation.

  The usage model is that the PEIM that discovers the permanent memory shall invoke this service.
  This routine will hold discoveried memory information into PeiCore's private data,
  and set SwitchStackSignal flag. After PEIM who discovery memory is dispatched,
  PeiDispatcher will migrate temporary memory to permanent memory.

  @param PeiServices        An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
  @param MemoryBegin        Start of memory address.
  @param MemoryLength       Length of memory.

  @return EFI_SUCCESS Always success.

**/
EFI_STATUS
EFIAPI
PeiInstallPeiMemory (
  IN CONST EFI_PEI_SERVICES  **PeiServices,
  IN EFI_PHYSICAL_ADDRESS    MemoryBegin,
  IN UINT64                  MemoryLength
  )

一句话:当BIOS执行完 PlatformPei.efi 之后内存可用。

Temp Stack : BaseAddress=0x818000 Length=0x8000
Temp Heap  : BaseAddress=0x810000 Length=0x8000
Total temporary memory:    65536 bytes.
  temporary memory stack ever used:       29192 bytes.
  temporary memory heap used for HobList: 6608 bytes.
  temporary memory heap occupied by memory pages: 0 bytes.
Memory Allocation 0x0000000A 0x7F78000 - 0x7FFFFFF
Memory Allocation 0x0000000A 0x810000 - 0x81FFFF
Memory Allocation 0x0000000A 0x807000 - 0x807FFF
Memory Allocation 0x0000000A 0x800000 - 0x805FFF
Memory Allocation 0x0000000A 0x806000 - 0x806FFF
Memory Allocation 0x00000006 0x7EF4000 - 0x7F77FFF
Memory Allocation 0x0000000A 0x820000 - 0x8FFFFF
Memory Allocation 0x00000004 0x900000 - 0x14FFFFF
Old Stack size 32768, New stack size 131072
Stack Hob: BaseAddress=0x3F36000 Length=0x20000
Heap Offset = 0x3746000 Stack Offset = 0x3736000
TemporaryRamMigration(0x810000, 0x3F4E000, 0x10000)

在运行PeiCheckAndSwitchStack() 函数的过程中输出上述Log。之后,再次跳入 PeiCore 进行执行,此时内存已经 Ready。

      //
      // Entry PEI Phase 2
      //
      PeiCore (SecCoreData, NULL, Private);

我们能够看到的Log 如下:

Loading PEIM 52C05B14-0B98-496C-BC3B-04B50211D680
Loading PEIM at 0x00007EE7000 EntryPoint=0x00007EE7538 PeiCore.efi
Reinstall PPI: 8C8CE578-8A3D-4F1C-9935-896185C32DD3
Reinstall PPI: 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A
Reinstall PPI: B9E0ABFE-5979-4914-977F-6DEE78C278A6
Install PPI: F894643D-C449-42D1-8EA8-85BDD8C65BDE
Loading PEIM 9B3ADA4F-AE56-4C24-8DEA-F03B7558AE50
Loading PEIM at 0x00007EE1000 EntryPoint=0x00007EE14C8 PcdPeim.efi
Reinstall PPI: 06E81C58-4AD7-44BC-8390-F10265F72480
Reinstall PPI: 4D8B155B-C059-4C8F-8926-06FD4331DB8A
Reinstall PPI: 01F34D25-4DE2-23AD-3FF3-36353FF323F1
Reinstall PPI: A60C6B59-E459-425D-9C69-0BCC9CB27D81

就是说再次进入 Peicore 之后重新执行了 PcdPeim.efi。

发表评论

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