UEFI中PEI阶段概总

----------------------------------------整体流程

  1. UEFI一个重要特点就是其模块化设计。PEI也是一个模块,PEI Image的入口函数位_ModuleEntryPoit,该函数最终调用PEI模块的入口函数PeiCore。
  2. 进入PeiCore后,首先根据SEC阶段传进来的信息设置Pei Core Services。
  3. 信息设置完成后,调用PeiDispatcher执行PEIM;
  4. 内存初始化。
  5. 当内存初始化后,系统会发生栈切换并重新进入PeiCore,重新进入到PeiCore后使用的内存是我们熟悉的内存。
  6. 待所有PEIM执行完后,调用PeiServices的LocatePpi服务得到DXE IPL PPI的Entry服务,这个Entry服务实际上是DxeLoadCore,它找出DXE Image的入口函数,执行DXE Image的入口函数并将HOB列表传递给DXE。

----------------------------------------特点

  • PEI阶段资源依然十分有限,内存到了PEI后期才被初始化。其主要功能是为DXE准备执行环境,将需要传递给DXE的信息组成HOB(Handoff Block)列表,最终将控制权交给DXE。
  • 从功能上讲,PEI可分为两个部分:PEI C/PEIM
  • PEI Core Services(PEI Foundation)负责PEI基础服务和流程;
  • PEIM(PEI Module)Dispatch。主要功能是找出系统中所有PEIM,并根据PEIM之间的依赖关系按顺序执行PEIM。
  • PEI阶段对系统的初始化主要是由PEIM完成的(CPU初始化、Chipset初始化、内存控制器初始化、IO控制器初始化、内存初始化等功能)。
  • 每个PEIM是一个独立模块,模块的入口函数传入两个参数,FileHandle和**PeiServices。通过PEIServices,PEIM可以使用PEI阶段提供的系统服务,通过这些服务,PEIM可以访问PEI Core。PEIM之间通过PPI(PEIM-to-PEIM Interface)完成。
  • PPI与DXE阶段的Protocol类似,每个PPI都是一个结构体,包含了函数指针和变量。每个PPI都有对应的GUID,通过PeiService的LocatePpi服务可以得到该PPI实例。

----------------------------------------代码流程

  • SEC阶段通过(*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable); 这段代码跳转到MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.c中的

VOID EFIAPI
_ModuleEntryPoint(                                                                                                                                              
  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,
  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList

)

  • 这个函数又调用ProcessModuleEntryPointList (SecCoreData, PpiList, NULL);函数,这个函数位于AutoGen.c中,这个文件是脚本生成的,在这个函数中调用了PeiCore入口函数

VOID EFIAPI
ProcessModuleEntryPointList (
  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,
  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,
  IN VOID                           *Context
  )

  •   这个函数又调用PeiCore (SecCoreData, PpiList, Context);       这样便跳转到了Pei阶段。

----------------------------------------

EFI_PEI_SERVICES  gPs = {
  {
    PEI_SERVICES_SIGNATURE,                  
    PEI_SERVICES_REVISION,                   
    sizeof (EFI_PEI_SERVICES),               
    0,
    0
  },
  PeiInstallPpi,
  PeiReInstallPpi,
  PeiLocatePpi,
  PeiNotifyPpi,

  PeiGetBootMode,
  PeiSetBootMode,

  PeiGetHobList,
  PeiCreateHob,

  PeiFfsFindNextVolume,
  PeiFfsFindNextFile,
  PeiFfsFindSectionData,                                                                                                                                                                      

  PeiInstallPeiMemory,      
  PeiAllocatePages,
  PeiAllocatePool,
  (EFI_PEI_COPY_MEM)CopyMem,
  (EFI_PEI_SET_MEM)SetMem,

  PeiReportStatusCode,
  PeiResetSystem,

  &gPeiDefaultCpuIoPpi,
  &gPeiDefaultPciCfg2Ppi,

  PeiFfsFindFileByName,
  PeiFfsGetFileInfo,
  PeiFfsGetVolumeInfo,
  PeiRegisterForShadow,
  PeiFfsFindSectionData3,
  PeiFfsGetFileInfo2,
  PeiResetSystem2,
  PeiFreePages,
};

----------------------------

typedef struct {
  UINTN     Flags;
  EFI_GUID  *Guid;
  VOID      *Ppi;     ===>
} EFI_PEI_PPI_DESCRIPTOR;

 

struct _EFI_PEI_FIRMWARE_VOLUME_INFO_PPI {
  EFI_GUID  FvFormat;
  VOID      *FvInfo;     ===>
  UINT32    FvInfoSize;
  EFI_GUID  *ParentFvName;
  EFI_GUID  *ParentFileName;
};

-----------------------------------------------------------------------------------------------------------------------------

struct _PEI_CORE_INSTANCE {
  UINTN                              Signature;
  EFI_PEI_SERVICES                   *Ps;              ==========> 1 //指向本结构成员ServiceTableShadow
  PEI_PPI_DATABASE                   PpiData;            ==========> 2 
  UINTN                              FvCount;
  PEI_CORE_FV_HANDLE                 *Fv;                       ==========> 3 数组指针
  PEI_CORE_UNKNOW_FORMAT_FV_INFO     *UnknownFvInfo;      ==========> 4 数组指针
  UINTN                              UnknownFvInfoCount;

 EFI_PEI_FILE_HANDLE                *CurrentFvFileHandles;       ==========>5
  UINTN                              AprioriCount;
  UINTN                              CurrentPeimFvCount;
  UINTN                              CurrentPeimCount;
  EFI_PEI_FILE_HANDLE                CurrentFileHandle;
  BOOLEAN                            PeimNeedingDispatch;
  BOOLEAN                            PeimDispatchOnThisPass;
  BOOLEAN                            PeimDispatcherReenter;
  EFI_PEI_HOB_POINTERS               HobList;                ==========>6
  BOOLEAN                            SwitchStackSignal;
  BOOLEAN                            PeiMemoryInstalled;
  VOID                               *CpuIo;
  EFI_PEI_SECURITY2_PPI              *PrivateSecurityPpi; 
  EFI_PEI_SERVICES                   ServiceTableShadow;         ==========>1
  EFI_PEI_PPI_DESCRIPTOR             *XipLoadFile;
  EFI_PHYSICAL_ADDRESS               PhysicalMemoryBegin;
  UINT64                             PhysicalMemoryLength;
  EFI_PHYSICAL_ADDRESS               FreePhysicalMemoryTop;
  UINTN                              HeapOffset;
  BOOLEAN                            HeapOffsetPositive;
  UINTN                              StackOffset;
  BOOLEAN                            StackOffsetPositive;
  HOLE_MEMORY_DATA                   MemoryPages;
  PEICORE_FUNCTION_POINTER           ShadowedPeiCore;
  CACHE_SECTION_DATA                 CacheSection;
  EFI_PHYSICAL_ADDRESS               LoadModuleAtFixAddressTopAddress;

UINT64                            *PeiCodeMemoryRangeUsageBitMap;
  PE_COFF_LOADER_READ_FILE          ShadowedImageRead;
  EFI_PEI_FILE_HANDLE               *FileHandles;
  EFI_GUID                          *FileGuid;                ==========>7
  HOLE_MEMORY_DATA                  HoleData[HOLE_MAX_NUMBER];
};
 ==========> 1

struct _EFI_PEI_SERVICES {
  EFI_TABLE_HEADER                Hdr;
  EFI_PEI_INSTALL_PPI             InstallPpi;
  EFI_PEI_REINSTALL_PPI           ReInstallPpi;
  EFI_PEI_LOCATE_PPI              LocatePpi;
  EFI_PEI_NOTIFY_PPI              NotifyPpi;
  EFI_PEI_GET_BOOT_MODE           GetBootMode;
  EFI_PEI_SET_BOOT_MODE           SetBootMode;
  EFI_PEI_GET_HOB_LIST            GetHobList;
  EFI_PEI_CREATE_HOB              CreateHob;
  EFI_PEI_FFS_FIND_NEXT_VOLUME2   FfsFindNextVolume;
  EFI_PEI_FFS_FIND_NEXT_FILE2     FfsFindNextFile;
  EFI_PEI_FFS_FIND_SECTION_DATA2  FfsFindSectionData;

 EFI_PEI_INSTALL_PEI_MEMORY      InstallPeiMemory;
  EFI_PEI_ALLOCATE_PAGES          AllocatePages;
  EFI_PEI_ALLOCATE_POOL           AllocatePool;
  EFI_PEI_COPY_MEM                CopyMem;
  EFI_PEI_SET_MEM                 SetMem;
  EFI_PEI_REPORT_STATUS_CODE      ReportStatusCode;
  EFI_PEI_RESET_SYSTEM            ResetSystem;
  EFI_PEI_CPU_IO_PPI              *CpuIo;
  EFI_PEI_PCI_CFG2_PPI            *PciCfg;
  EFI_PEI_FFS_FIND_BY_NAME        FfsFindFileByName;
  EFI_PEI_FFS_GET_FILE_INFO       FfsGetFileInfo;
  EFI_PEI_FFS_GET_VOLUME_INFO     FfsGetVolumeInfo;
  EFI_PEI_REGISTER_FOR_SHADOW     RegisterForShadow;
  EFI_PEI_FFS_FIND_SECTION_DATA3  FindSectionData3;
  EFI_PEI_FFS_GET_FILE_INFO2      FfsGetFileInfo2;
  EFI_PEI_RESET2_SYSTEM           ResetSystem2;
  EFI_PEI_FREE_PAGES              FreePages;
};

 ==========> 2

typedef struct {
  INTN                    PpiListEnd;
  INTN                    NotifyListEnd;            //PcdGet32 (PcdPeiCoreMaxPpiSupported)-1
  INTN                    DispatchListEnd;             //PcdGet32 (PcdPeiCoreMaxPpiSupported)-1
  INTN                    LastDispatchedInstall;     //PcdGet32 (PcdPeiCoreMaxPpiSupported)-1 
  INTN                    LastDispatchedNotify;              
  PEI_PPI_LIST_POINTERS   *PpiListPtrs;   ==========> 数组列表 2.1
} PEI_PPI_DATABASE; 

 ==========> 2.1

typedef union {
  EFI_PEI_PPI_DESCRIPTOR      *Ppi;                ==========> 2.1.1
  EFI_PEI_NOTIFY_DESCRIPTOR   *Notify;      ==========> 2.1.2
  VOID                        *Raw;
} PEI_PPI_LIST_POINTERS;

==========> 2.1.1

typedef struct {
  UINTN     Flags;                
  EFI_GUID  *Guid;
  VOID      *Ppi;
} EFI_PEI_PPI_DESCRIPTOR

==========> 2.1.2

struct _EFI_PEI_NOTIFY_DESCRIPTOR {                                                                                                                                                          
  UINTN                       Flags; 
  EFI_GUID                    *Guid; 
  EFI_PEIM_NOTIFY_ENTRY_POINT Notify;  (函数)
};

==========> 3

typedef struct {
  EFI_FIRMWARE_VOLUME_HEADER          *FvHeader;     =====>3.1
  EFI_PEI_FIRMWARE_VOLUME_PPI         *FvPpi;        ======> 3.2
  EFI_PEI_FV_HANDLE                   FvHandle;                (空间)
  UINT8                               *PeimState;                        
  EFI_PEI_FILE_HANDLE                 *FvFileHandles;
  BOOLEAN                             ScanFv;                             
  UINT32                              AuthenticationStatus;               
} PEI_CORE_FV_HANDLE; 

=====>3.1

typedef struct {
  UINT8                     ZeroVector[16];
  EFI_GUID                  FileSystemGuid;
  UINT64                    FvLength;
  UINT32                    Signature;
  EFI_FVB_ATTRIBUTES_2      Attributes;
  UINT16                    HeaderLength;
  UINT16                    Checksum;
  UINT16                    ExtHeaderOffset;
  UINT8                     Reserved[1];

  UINT8                     Revision;
  EFI_FV_BLOCK_MAP_ENTRY    BlockMap[1];
} EFI_FIRMWARE_VOLUME_HEADER;

=====>3.2

struct _EFI_PEI_FIRMWARE_VOLUME_PPI {
  EFI_PEI_FV_PROCESS_FV         ProcessVolume;                                                                                                  
  EFI_PEI_FV_FIND_FILE_TYPE   FindFileByType;
  EFI_PEI_FV_FIND_FILE_NAME   FindFileByName;
  EFI_PEI_FV_GET_FILE_INFO    GetFileInfo;
  EFI_PEI_FV_GET_INFO         GetVolumeInfo;
  EFI_PEI_FV_FIND_SECTION     FindSectionByType;
  EFI_PEI_FV_GET_FILE_INFO2   GetFileInfo2;
  EFI_PEI_FV_FIND_SECTION2    FindSectionByType2;
  UINT32                      Signature;
  UINT32                      Revision;
};

==========> 4

typedef struct {
  EFI_GUID                            FvFormat;                           
  VOID                                *FvInfo;                            
  UINT32                              FvInfoSize;                         
  UINT32                              AuthenticationStatus;               
  EFI_PEI_NOTIFY_DESCRIPTOR           NotifyDescriptor;
} PEI_CORE_UNKNOW_FORMAT_FV_INFO;

  ==========>5
/// The handles of EFI FFS.
typedef VOID    *EFI_PEI_FILE_HANDLE;

  ==========>6

typedef union {
  EFI_HOB_GENERIC_HEADER              *Header;
  EFI_HOB_HANDOFF_INFO_TABLE          *HandoffInformationTable;
  EFI_HOB_MEMORY_ALLOCATION           *MemoryAllocation;
  EFI_HOB_MEMORY_ALLOCATION_BSP_STORE *MemoryAllocationBspStore;
  EFI_HOB_MEMORY_ALLOCATION_STACK     *MemoryAllocationStack;
  EFI_HOB_MEMORY_ALLOCATION_MODULE    *MemoryAllocationModule;
  EFI_HOB_RESOURCE_DESCRIPTOR         *ResourceDescriptor;
  EFI_HOB_GUID_TYPE                   *Guid;
  EFI_HOB_FIRMWARE_VOLUME             *FirmwareVolume;
  EFI_HOB_FIRMWARE_VOLUME2            *FirmwareVolume2;
  EFI_HOB_FIRMWARE_VOLUME3            *FirmwareVolume3;
  EFI_HOB_CPU                         *Cpu;
  EFI_HOB_MEMORY_POOL                 *Pool;
  EFI_HOB_UEFI_CAPSULE                *Capsule;
  UINT8                               *Raw;  // 将SecCoreData->PeiTemporaryRamBase
} EFI_PEI_HOB_POINTERS; 

-----------------------------------------------------------------------------------------------------------------------------

typedef struct { //包含Hob产生器阶段使用的一般状态信息。这个Hob必须是Hob列表中的第一个。

  EFI_HOB_GENERIC_HEADER  Header;
  UINT32                  Version;
  EFI_BOOT_MODE           BootMode;
  EFI_PHYSICAL_ADDRESS    EfiMemoryTop;
  EFI_PHYSICAL_ADDRESS    EfiMemoryBottom;
  EFI_PHYSICAL_ADDRESS    EfiFreeMemoryTop;
  EFI_PHYSICAL_ADDRESS    EfiFreeMemoryBottom;
  EFI_PHYSICAL_ADDRESS    EfiEndOfHobList;
} EFI_HOB_HANDOFF_INFO_TABLE;           

typedef struct {
  EFI_HOB_GENERIC_HEADER Header;   ====>
  EFI_PHYSICAL_ADDRESS   BaseAddress;      (空间)
  UINT64                 Length;
} EFI_HOB_FIRMWARE_VOLUME;

typedef struct { //描述Hob内数据的格式和大小。所有的Hob都必须包含这个通用的Hob头。

  UINT16    HobType;
  UINT16    HobLength;
  UINT32    Reserved;
} EFI_HOB_GENERIC_HEADER;

-----------------------------------------------------------------------------------------------------------------------------

struct _EFI_PEI_NOTIFY_DESCRIPTOR {
  UINTN                       Flags; 
  EFI_GUID                    *Guid; 
  EFI_PEIM_NOTIFY_ENTRY_POINT Notify;
};

typedef
EFI_STATUS
(EFIAPI *EFI_PEIM_NOTIFY_ENTRY_POINT)(
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,                                                                                                                                            
  IN VOID                       *Ppi
  );

-----------------------------------------------------------------------------------------------------------------------------

PeiCore函数分析:

VOID
EFIAPI
PeiCore (
  IN CONST EFI_SEC_PEI_HAND_OFF        *SecCoreDataPtr,
  IN CONST EFI_PEI_PPI_DESCRIPTOR    *PpiList,                                                                                                                             
  IN VOID                              *Data
  )

  1. PEI_CORE_INSTANCE结构的创建,填充成员ServiceTableShadow。为全局的gPs
  2. PEI_CORE_INSTANCE结构成员Ps=PEI_CORE_INSTANCE结构ServiceTableShadow。
  3. 通过SetPeiServicesTablePointer()保存Ps,以便可以在任何地方检索它。由全局的gPeiServices维护
  4. 通过ProcessLibraryConstructorList(),传入Ps指针,初始化PEI核心所链接的库。
  5. 通过InitializeMemoryServices(),传入PrivateData,    SecCoreData,初始化PEI Core,即根据PeiTemporaryRamBase,和PeiTemporaryRamSize构建一个切换信息表HOB(  一个EFI_HOB_GENERIC_HEADER和一个EFI_HOB_GENERIC_HEADER,这些都在PeiTemporaryRamBase起始位置)。
  6. 初始化PEI核心私有数据缓冲区。
  7. 通过InitializePpiServices()初始化ppi 服务。PEI_PPI_DATABASE     PpiData。
  8. 通过InitializeSecurityServices(),传入PrivateData.Ps,初始化 安全服务(全局变量mNotifyList)
  9. 通过InitializeDispatcherData(),传入PrivateData,    SecCoreData,初始化调度程序的数据成员
  10. 通过InitializeImageServices(),传入PrivateData,   安装PEI加载PPI文件。
  11. 通过ProcessPpiListFromSec(),如果SEC提供了PpiList,就处理。
  12. 通过PeiDispatcher(),回调PEIM调度员。开展PEIM调度。
  13. 通过PeiServicesLocatePpi(),查找DXE IPL PPI。
  14. 输入Dxe Ipl来加载Dxe内核。TempPtr.DxeIpl->Entry (TempPtr.DxeIpl,  &PrivateData.Ps,  PrivateData.HobList  );

 

------------------------------------------------------构建一个切换信息表HOB

  • 一个EFI_HOB_GENERIC_HEADER:Hob

  EFI_HOB_GENERIC_HEADER  Header;

    /*UINT16    HobType;  // =EFI_HOB_TYPE_HANDOFF
    /*UINT16    HobLength;    //  =sizeof (EFI_HOB_GENERIC_HEADER)
    /*UINT32    Reserved;     //=0

  UINT32                  Version;  // =EFI_HOB_HANDOFF_TABLE_VERSION
  EFI_BOOT_MODE           BootMode;  // = BOOT_WITH_FULL_CONFIGURATION,
  EFI_PHYSICAL_ADDRESS    EfiMemoryTop;  //PeiTemporaryRamBase+ PeiTemporaryRamSize,
  EFI_PHYSICAL_ADDRESS    EfiMemoryBottom;  // PeiTemporaryRamBase,
  EFI_PHYSICAL_ADDRESS    EfiFreeMemoryTop;  //PeiTemporaryRamBase +PeiTemporaryRamSize,;
  EFI_PHYSICAL_ADDRESS    EfiFreeMemoryBottom;  // (HobEnd + 1)
  EFI_PHYSICAL_ADDRESS    EfiEndOfHobList;   // HobEnd
} EFI_HOB_HANDOFF_INFO_TABLE;           

  • 一个EFI_HOB_GENERIC_HEADER:HobEnd

  UINT16    HobType;  // =EFI_HOB_TYPE_END_OF_HOB_LIST
  UINT16    HobLength;    // =sizeof (EFI_HOB_GENERIC_HEADER)
  UINT32    Reserved;      // =0

 

 

  • 6
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值