PEI阶段扩展 |
您所在的位置:网站首页 › efi啥意思 › PEI阶段扩展 |
PEI阶段扩展
OVERVIEWPEIMPPIUSE PPIInstall PPILocatePPI()Notifyppi()
HOBHOB的使用
OVERVIEW
本篇补充相关PEI到DXE阶段的一写知识 在PEI阶段,PEIM 、PPI、 HOB组成了PEI阶段的最重要的部分,PEI阶段的module也可以理解为Driver就是PEIM,PEI阶段就是由一个一个的PEIM组成的;PPI是PEIM之间互相调用的接口,由惟一的GUID引导,内部也包含一些接口,HOB相当于信件在PEI阶段创建,会记载当前系统的信息,可以自定义HOB,然后在DXE阶段读取。框图如下: PEIM(PEI Module), 会被编译成efi binary,在一套完整的BIOS code编译完之后进入到build目录就可以找到这个PEIM具体的efi,.inf + .c +.h >build> .efi是为了硬件相关的初始化,PEIM 也提供各自提供接口(interface)给别的PEIM使用 PPIs (PEIM-to-PEIM Interfaces) PEIMs被调用是通过PPI,Interface。Interface是UEFI重要的概念,会经常出现。简单来说,PPI只是一个接口,接口里面有成员函数,想调用某个函数必须通过该接口。PPI的名字:GUID (128-bits value)PPIs被定义成结构体的形式,在code里看PPI就是一个Struct,其中可能包括功能、数据,或者两者的混合。PEIM会把它的PPI注册到PEI Foundation,PEI Foundation管理着庞大的PPI数据库 USE PPI几个重要的PPI Services InstallPpi() 安装PPI到PEI foundation,protocol install完后是放到Handle Datebase里面LocatePpi() 根据PPI名字GUID从PEI foundation找InterfaceNotifyPpi() PPI里的function不会在派发时就执行,会有一个判定条件,通知系统这个PPI会在某个PPI被安装时才执行。 Install PPI /** Install PPI services. It is implementation of EFI_PEI_SERVICE.InstallPpi. 这是个service,PEI foundation提供的。 通过GUID安装。目的是让别人调用。 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. 标准格式,入口第一人参数是铁定的EFI_PEI_SERVICES指针 @param PpiList Pointer to PPI array that want to be installed. 第二个参数是PPI List, LIST里包括Flag、GUID和函数 参考.h里的EFI_PEI_PPI_DESCRIPTOR定义 @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed. @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer if any PPI in PpiList is not valid @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI **/ EFI_STATUS EFIAPI PeiInstallPpi ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList );实例: 以下面的PPI为例,一个给Capsule服务的PPI,里面有三个成员 CapsuleCoalesce, CheckCapsuleUpdate, CreateState。 CONST EFI_PEI_CAPSULE_PPI mCapsulePpi = { CapsuleCoalesce, CheckCapsuleUpdate, CreateState };给InstallPPI传递的第二个参数:*PpiList。Descriptor有三个值,第一个为属性,第二个为绑定的GUID用于后面locate调用,第三个参数放入struct接口,这样就定义好了ppiList。 PeiServicesInstallPpi原型函数,还是那个标准的InstallPpi,传了两个参数This指针和PpiList EFI_PEI_PPI_DESCRIPTOR // // PEI Ppi Services List Descriptors // #define EFI_PEI_PPI_DESCRIPTOR_PIC 0x00000001 #define EFI_PEI_PPI_DESCRIPTOR_PPI 0x00000010 #define EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK 0x00000020 #define EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH 0x00000040 #define EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES 0x00000060 #define EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST 0x80000000 /// /// The data structure through which a PEIM describes available services to the PEI Foundation. /// typedef struct { /// /// This field is a set of flags describing the characteristics of this imported table entry. /// All flags are defined as EFI_PEI_PPI_DESCRIPTOR_***, which can also be combined into one. /// 上面描述的属性。 UINTN Flags; /// /// The address of the EFI_GUID that names the interface. /// 所绑定的GUID EFI_GUID *Guid; /// /// A pointer to the PPI. It contains the information necessary to install a service. /// 所需要install的PPI VOID *Ppi; } EFI_PEI_PPI_DESCRIPTOR; LocatePPI() /** Locate a given named PPI. 用GUID从Database中找想要的PPI @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. @param Guid Pointer to GUID of the PPI. @param Instance Instance Number to discover. @param PpiDescriptor Pointer to reference the found descriptor. If not NULL, returns a pointer to the descriptor (includes flags, etc) @param Ppi Pointer to reference the found PPI @retval EFI_SUCCESS if the PPI is in the database @retval EFI_NOT_FOUND if the PPI is not in the database **/ EFI_STATUS EFIAPI PeiLocatePpi ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi ); //第一个参数是固定的EFI_PEI_SERVICES第二个参数为GUID,第三个参数通常为0,第四个参数为NULL最重要是拿到第五个参数,通过这个指针可以得到Interface。实例: 以Capsule为例:Guid为gEfiPeiCapsulePpiGuid,通过这个GUID从Database中找想要的PPI, 想要的PPI都在这个Capsule指针里,Locate之后就可以调用PPI里的函数实现CheckCapsuleUpdate功能 实例:当这个gEfiEndOfPeiSignalPpiGuid指向的PPI被安装时才会触发S3EndOfPeiNotify() HOB (Hand-Off Blocks )传输信息的载体,相比于其他Phase之间的联系,Pei到DXE之间联系比较薄弱,PEI一些初始化硬件、内存的数据等,DXE需要知道,HOB便作为桥梁应运而生。 HOB producer phase (PEI phase)HOB consumer phase (PEI & DXE phase) (如getbootmodehob就是在PEI阶段调用的,但DXE阶段是不能产生HOB的)HOB实际上就是一个链表,当我们找到一个hoblist的头,那么整个链表的数据都能get到,比如说GetHobList(),会直接获取hoblist的指针,而且第一个HOB总是为PHIT == Phase Handoff Information Table,里面是boot mode 其它HOB可能出现在List任意位置, 最重要的是System Memory HOB & Firmware Volumes, HOB列表总是会以END_OF_HOB_LIST结束 下图中没有显示的另一个HOB类型是GUID HOB,它允许PEIM将私有数据传递给DXE驱动程序。
传入的参数第一个为Hob的GUID,所有的UEFI元素都有自己的GUID,传入得到的返回结果就是HOBlist ,通过的是configration table去抓的(属于systemtable的成员),每个DXE Driver的entrypoint都有两个参数imaginehandle 和systemtable,故而可以通过systemtable可以访问整个系统的资源。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |