如何网站平台建设好公司网络规划与设计论文
UEFI系列文章目录
第一章 SEC阶段讲解
 第二章 PEI阶段讲解
文章目录
- UEFI系列文章目录
 - 前言
 - 一、PEI阶段
 - 二、PEI Service
 - 三、PEI flow
 - 四、InstallPpi和LocatePpi举例
 - 五、Hob
 - 六、PEI入口和出口
 
前言
众所周知,UEFI bios分为四个阶段:SEC、PEI、DXE、BDS,运行完毕才能进到setup界面或是进入操作系统。
 x86平台较为经典,而ARM在UEFI之前需要运行ATF(Arm Trusted Firmware),ATF做了SEC和PEI的部分工作,且ARM部分平台不需要PEI。
 
这篇文章着重介绍UEFI bios的PEI阶段。
提示:以下皆基于x86 UEFI bios
一、PEI阶段
PEI: Pre-EFI initialization 预初始化阶段
1.为什么需要PEI?
内存还未初始化。
 芯片组还未初始化。
 ROM上要执行的code还没被解压。
2.PEI阶段做了哪些事情?
- CPU\芯片组\内存初始化
 - 把PEI阶段收集到的某些信息会存放进Hob,传递给下一个阶段:DXE
 - 控制权交给DXE
 - 固件损坏后的紧急修复(recovery)
 - 从 S3 睡眠状态(CPU停止工作,挂起到内存RAM)恢复
(Disable CAR, Eable Cache恢复成缓存本身的作用) 
3.PEI组成元素
- PEI Core
为提供PEIMservice
加载执行PEIM - PEI Service
PEl Core服务例程(函数),所有PEIM都可以使用它们 - PEIM
意思是PEI Module,PEI阶段执行模块的type名 - PPI
PEl to PEl Interface , PEIM为其他PEIM提供调用接口
(需要其他地方install了才能去locate) 
二、PEI Service
1.PPI Service
 {InstallPpi
 ReInstallPpi
 LocatePpi
 NotifyPpi
 }
 2.Boot Mode Services | s3、s4、s5、recovery、flash更新等
 {GetBootMode
 SetBootMode
 }
 3.HOB Services
 {CreateHob
 GetHobList
 }
 4.Firmware Volume Service | 固件空间
 {FfsFindNextVolume
 FfsFindNextFile
 FfsFindSectionData
 }
 5.PEI Memory Service | 内存
 {
 InstallPeiMemory
 AllocatePages
 AllocatePool
 CopyMem
 SetMem
 }
 6.Status Code Service | 状态
 {ReportStatusCode
 }
 7.Reset Service
 {ResetSystem
 }
其中ppi相关非常重要。
 installppi是安装ppi,每个ppi都有其特定的guid,写了不同的功能后installppi来安装好。后续可通过在需要的地方locateppi调用。
 reinstallppi就是字面上的重新安装。
 notifyppi一种类似中断的回调触发,在对应的ppi被install或reinstall会触发。
Hob的CreateHobH和GetHobList其实都是PEI时用的,前者是创建Hob,后者是获取HobList的地址(要想找到自己创建的hob,还需调用其他函数和循环来找,比如通过当时存储的guid)。
ReportStatusCode是往80 port上写值。
三、PEI flow
- 初始化PEI Core
 - 有序dispatch分发PEIM执行(执行的PEIM都会有一个entry point入口函数)
如果设置了priority的话会按照优先级顺序执行,也会按照依赖里的guid是否install上去,没装上去就靠后、等待guid装上去了再执行。 - PEI Core dispatch DXE Ipl结束,load进DXE
 
四、InstallPpi和LocatePpi举例
举例InstallPpi:
 1.定义guid gCMOSREADWRITEGuid和我要执行的功能CMOSPpi
EFI_GUID gCMOSREADWRITEGuid={0x41122338, 0x5678, 0x1234, {0x22, 0x55, 0x56, 0xe7, 0x55, 0xb2, 0x78, 0x77}};
void peiwritecmos8(UINT8 OFFSET,UINT8 DATA){IoWrite8(WRITE_READ_INDEX,OFFSET);IoWrite8(WRITE_READ_DATA,DATA);  }
UINT8 peireadcmos8( UINT8 OFFSET_READ){IoWrite8(WRITE_READ_INDEX,OFFSET_READ);return IoRead8(WRITE_READ_DATA);}
typedef void(EFIAPI *WRITE_CMOS)(UINT8 OFFSET,UINT8 DATA);
typedef UINT8(EFIAPI *READ_CMOS)(UINT8 OFFSET_READ);
typedef struct SHOW_CMOS{WRITE_CMOS peiwritecmos8;READ_CMOS  peireadcmos8;
}CMOS_READ_WRITE;static CMOS_READ_WRITE CMOSPpi ={peiwritecmos8,peireadcmos8 
};
 
2.拿着gCMOSREADWRITEGuid、CMOSPpi,按照格式写EFI_PEI_PPI_DESCRIPTOR结构CMOS_PPI_WRITE_READ
static EFI_PEI_PPI_DESCRIPTOR CMOS_PPI_WRITE_READ[]= {
{ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,&gCMOSREADWRITEGuid, &CMOSPpi}
};
 
入口函数内:将写好的CMOS_PPI_WRITE_READ拿来安装
(*PeiServices)->InstallPpi(PeiServices, CMOS_PPI_WRITE_READ);
 
举例LocatePpi:
EFI_GUID gCMOSREADWRITEGuid={0x41122338, 0x5678, 0x1234, {0x22, 0x55, 0x56, 0xe7, 0x55, 0xb2, 0x78, 0x77}};
typedef void(EFIAPI *WRITE_CMOS)(UINT8 OFFSET,UINT8 DATA);
typedef UINT8(EFIAPI *READ_CMOS)(UINT8 OFFSET_READ);
typedef struct SHOW_CMOS{WRITE_CMOS peiwritecmos8;READ_CMOS  peireadcmos8;
}CMOS_READ_WRITE;//入口函数内
CMOS_READ_WRITE         *readwritecmosppi;(*PeiServices)->LocatePpi(PeiServices,&gCMOSREADWRITEGuid, //写guid0,NULL,&readwritecmosppi //获取的函数) ; if((readwritecmosppi->peireadcmos8(0x38))!=0){//调用函数readwritecmosppi->peiwritecmos8(0x39,0xf);} 
五、Hob
Hob是用来存放信息的东西,用于PEI获取的信息传递给DXE(可以使内存的信息、IO的信息等等)。HobList以PHIT HOB开头,之后的Hob排列呈链表。
 
 Hob类型:
 PHIT Hob,作为头Hob
 描述物理内存信息Hob
 内存空间分配Hob
 Fv Hob
 …
PEI主要分为3个阶段:
 1.Pre memory
 2.post memory:HobList - Termination、FV、physical memory、PHIT
 4.DXE IPL(最后的PEIM):HobList - Termination、GUID Hobs、DXE Stack/BSP、DXE Core、FV、physical memory、PHIT
DXE Main就可以获取到HobList
Create a Hob代码
typedef struct [
EFI_HOB_GUID_TYPE EfiHobGuidType;
OEM_DEFIN_TYPE XXX;
}Demo_HOB; //Hob定义Status = (*PeiServices)->CreateHob(PeiServices,EFI_HOB_TYPE_GUID_EXTENSION, //属性:GUID_EXTENSIONsizeof(Demo_HOB),&DemoHob);
if (!EFI_ERROR(Status){ //赋值DemoHob->EfiHobGuidType.Name = gDemoGuid;DemoHob->xxx = YYY;
}
 
同EFI_HOB_TYPE_GUID_EXTENSION类似,还有其他HOB属性
 EFI_HOB_TYPE_HANDOFF
 EFI_HOB_TYPE_MEMORY_ALLOCATION
 EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
 EFI_HOB_TYPE_GUID_EXTENSION(查找的时候就用guid查找)
 EFI_HOB_TYPE_FV
 EFI_HOB_TYPE_CPU
 EFI_HOB_TYPE_MEMORY_POOL
 EFI_HOB_TYPE_CV
最后带着hoblist去DXE(这里是DXEIPL的函数):
 HandOffToDxeCore (DxeCoreEntryPoint, HobList);
六、PEI入口和出口
SEC带着SECCoreData和PPIList跳转PEIEntryPoint
 入口:PeiMain.c里的PeiCore
 (ps:pei service)
 内存初始化、pei内存分配、hoblist头创建、PPIlist获取、PEIM dispatch(先statuscode再nvram再其他)
 locate DXEIPL的ppi
 转到DXEIPL函数,一系类操作后BuildModuleHob来加Hob到DXE,再带着HobList和DxeCoreEntryPoint跳转HandOffToDxeCore
