PEI编程练习 - hob简单练习

阅读: 评论:0

PEI编程练习 - hob简单练习

PEI编程练习 - hob简单练习

一、HOB (Hand-off Block) 的认识

详情参考: Platform Initialization (PI) Specification

  • 在PEI Phase 中,使用的数据存储区就叫做HOBs,PEI可以使用HOB向DXE传递信息。
  • 在PEI Phase 中,HOBs是可读可写的,在DXE Phase中,只能读。
  • HOB是系列的连续的内存结构体,可以认为其由三部分构成:第一部分,是 Phase Handoff Information Table (PHIT) 头,它描述了HOB的起始地址以及总的内存使用;第二部分是各个Hob列表,DXE阶段会根据这一部分获取上关资源;第三部分是结束部分。
  • The first HOB in the HOB list must be the Phase Handoff Information
  • Table (PHIT) HOB. The last HOB in the HOB list must be the End of HOB List HOB. Only HOB producer phase components are allowed to make
    additions or changes to HOBs. Once the HOB list is passed into the
    HOB consumer phase, it is effectively read only. The ramification of
    a read-only HOB list is that handoff information, such as boot mode,
    must be handled in a distinguished fashion. For example, if the HOB
    consumer phase were to engender a recovery condition, it would not
    update the boot mode but instead would implement the action using a
    special type of reset call.
  • The HOB list contains system state data at the time of HOB producer–to–HOB producer handoff and does not represent the current
    system state during the HOB consumer phase.
  • The HOB list is initially built by the HOB producer phase. The HOB list is created in memory that is present, initialized, and tested.
    Once the initial HOB list has been created, the physical memory
    cannot be remapped, interleaved, or otherwise moved by a subsequent
    software agent.

翻译:

  • 在HOB List中的第一个HOB必须是PHIT HOB(Phase Handoff Information Table),最后一个HOB必须是End of HOB List HOB。
  • 只有PEI Phase才允许增加或改动这些HOBs,当HOB List被传送给DXE Phase之后,他们就是只读的(Read Only)。一个只读的HOB List的延伸就是Handoff 信息,比如Boot Mode,必须以别的方式来处理。比如,DXE
    Phase想要产生一个Recovery条件,它不能update Boot Mode,而是通过使用特殊方式的reset call来实现。
  • 在HOB中包含的系统状态数据(System State Data)是指在PEI to DXE Handoff的时候的系统状态,而不是代表DXE当前的系统状态。
  • HOB list是在PEI Phase被建立的,它存在于已经present,initialized,tested的Memory中。一旦最初的HOB
    List被创建,物理内存就不能被remapped, interleaved, 或者被后来的程序moved。
    HOB在PEI到DXE传送信息的过程遵循one Producer to one
    Consumer的模式,即在PEI阶段,一个PEIM创建一个HOB,在DXE阶段,一个DXE
    Driver使用那个HOB并且把HOB相关的信息传送给其他的需要这些信息的DXE组件。

HOB Construction Rules HOB construction must obey the following rules:

  1. All HOBs must start with a HOB generic header. This requirement allows users to locate the HOBs in which they are interested while
    skipping the rest. See the EFI_HOB_GENERIC_HEADER definition.
  2. HOBs may contain boot services data that is available during the HOB producer and consumer phases only until the HOB consumer phase is
    terminated.
  3. HOBs may be relocated in system memory by the HOB consumer phase. HOBs must not contain pointers to other data in the HOB list,
    including that in other HOBs. The table must be able to be copied
    without requiring internal pointer adjustment.
  4. All HOBs must be multiples of 8 bytes in length. This requirement meets the alignment restrictions of the Itanium ® processor family.
  5. The PHIT HOB must always begin on an 8-byte boundary. Due to this requirement and requirement #4 in this list, all HOBs will begin on an
    8-byte boundary.
  6. HOBs are added to the end of the HOB list. HOBs can only be added to the HOB list during the HOB producer phase, not the HOB consumer
    phase.
  7. HOBs cannot be deleted. The generic HOB header of each HOB must describe the length of the HOB so that the next HOB can be found. A
    private GUIDed HOB may provide a mechanism to mark some or its entire
    contents invalid; however, this mechanism is beyond the scope of this
    document.

翻译:
构造HOB必须遵循以下的规则:

  1. 每个HOB必须以一个HOB generic header开头(EFI_HOB_GENERIC_HEADER)。
  2. HOBs可以包含boot services data,在DXE Phase结束之前,PEI和DXE都可以调用。
  3. HOBs可以被DXE重新安置在系统内存上,每个HOB都不能包含指向HOB List中其他数据的指针,也不能指向其他的HOB,这个Table必须可以被Copied而不需要任何内部指针的调整。
  4. 所有的HOB在长度上必须是8 bytes的倍数,是alignment的要求。
  5. PHIT HOB必须总是在8 byte处开始。
  6. 增加的HOB总是被加到HOB List的最后,而且只能在PEI Phase(HOB Producer Phase)增加,DXE Phase(HOB Consumer Phase)不能。
  7. HOBs不能被删除。每个HOB的generic header中都会描述这个HOB的长度,这样下一个HOB就很容易被找到。

Adding to the HOB List

To add a HOB to the HOB list, HOB consumer phase software must obtain a pointer to the PHIT HOB (start of the HOB
list) and follow these steps:

  1. Determine NewHobSize, where NewHobSize is the size in bytes of the HOB to be created.
  2. Check free memory to ensure that there is enough free memory to allocate the new HOB. This test is performed by checking that
    NewHobSize <= PHIT->EfiFreeMemoryTop - PHIT->EfiFreeMemoryBottom).
  3. Construct the HOB at PHIT->EfiFreeMemoryBottom.
  4. Set PHIT->EfiFreeM

翻译:
增加新的HOB到HOB List中 PEI Phase(HOB Producer Phase)肯定包含一个指向PHIT
HOB(这是HOB List的开始)的指针,然后遵循以下的步骤:

  1. 确定NewHobSize,即确定要创建的HOB的大小(以Byte为单位)。
  2. 确定是否有足够的空闲内存分配给新的HOB(NewHobSize <= (PHIT->EfiFreeMemoryTop - PHIT->EfiFreeMemoryBottom))。
  3. 在(PHIT->EfiFreeMemoryBottom)处构建HOB。
  4. 设置PHIT->EfiFreeMemoryBottom = PHIT->EfiFreeMemoryBottom + NewHobSize 。

代码中表示:

EDK/edk2/MdePkg/Include/Pi/PiHob.h 中:
typedef struct {////// The HOB generic header. Header.HobType = EFI_HOB_TYPE_HANDOFF.///EFI_HOB_GENERIC_HEADER  Header;////// The version number pertaining to the PHIT HOB definition./// This value is four bytes in length to provide an 8-byte aligned entry/// when it is combined with the 4-byte BootMode.///UINT32                  Version;////// The system boot mode as determined during the HOB producer phase.///EFI_BOOT_MODE           BootMode;////// The highest address location of memory that is allocated for use by the HOB producer/// phase. This address must be 4-KB aligned to meet page restrictions of UEFI.///EFI_PHYSICAL_ADDRESS    EfiMemoryTop;////// The lowest address location of memory that is allocated for use by the HOB producer phase.///EFI_PHYSICAL_ADDRESS    EfiMemoryBottom;////// The highest address location of free memory that is currently available/// for use by the HOB producer phase.///EFI_PHYSICAL_ADDRESS    EfiFreeMemoryTop;////// The lowest address location of free memory that is available for use by the HOB producer phase.///EFI_PHYSICAL_ADDRESS    EfiFreeMemoryBottom;////// The end of the HOB list.///EFI_PHYSICAL_ADDRESS    EfiEndOfHobList;
} EFI_HOB_HANDOFF_INFO_TABLE;typedef struct {////// Identifies the HOB data structure type.///UINT16    HobType;////// The length in bytes of the HOB.///UINT16    HobLength;////// This field must always be set to zero.///UINT32    Reserved;
} EFI_HOB_GENERIC_HEADER;//
// HobType of EFI_HOB_GENERIC_HEADER.
//
#define EFI_HOB_TYPE_HANDOFF              0x0001
#define EFI_HOB_TYPE_MEMORY_ALLOCATION    0x0002
#define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR  0x0003
#define EFI_HOB_TYPE_GUID_EXTENSION       0x0004
#define EFI_HOB_TYPE_FV                   0x0005
#define EFI_HOB_TYPE_CPU                  0x0006
#define EFI_HOB_TYPE_MEMORY_POOL          0x0007
#define EFI_HOB_TYPE_FV2                  0x0009
#define EFI_HOB_TYPE_LOAD_PEIM_UNUSED     0x000A
#define EFI_HOB_TYPE_UEFI_CAPSULE         0x000B
#define EFI_HOB_TYPE_FV3                  0x000C
#define EFI_HOB_TYPE_UNUSED               0xFFFE
#define EFI_HOB_TYPE_END_OF_HOB_LIST      0xFFFF

二、hob简单练习

  1. 在PEI Phase建一个GUID类型的hob
  2. 在DXE Phase去使用这个hob

BuildGuidHob

c文件

PATH:

edk2/EmulatorPkg/TestByMy/PeiTest/MyFirstPeiHob/MyFirstHob.c

code:

/*++ @fileCopyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2011, Apple Inc. All rights reserved.**/
#include <Uefi.h>
#include <Uefi/UefiBaseType.h>
#include <Pi/PiPeiCis.h>
#include <Ppi/MemoryDiscovered.h>#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/HobLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/MemoryAllocationLib.h>/**This funtion is  printf  str in debug@return status
**/
EFI_STATUS
EFIAPI
PrintMesg (VOID)
{DEBUG ((DEBUG_INFO, "Mesg for in pei hob!n"));return EFI_SUCCESS;
}/**This funtion is  printf  str in debug@return status
**/
typedef 
EFI_STATUS 
(EFIAPI *PEI_HOB_MESSG) (VOID);typedef struct {INT32  number;PEI_HOB_MESSG  PrintMesg;
}TEST_STR;extern EFI_GUID gMyFirstHobGuid;EFI_STATUS
EFIAPI
MyFirstHobEntry(IN       EFI_PEI_FILE_HANDLE  FileHandle,IN CONST EFI_PEI_SERVICES     **PeiServices
)/*++
creat a hob for guid
Arguments:FfsHeader   - General purpose data available to every PEIMPeiServices - General purpose services available to every PEIM.Returns:None
**/
{EFI_STATUS                     Status;// EFI_HOB_MEMORY_ALLOCATION      *Hob; IN UINTN                       DataLength;TEST_STR                       *Data;TEST_STR                       *HobData;UINTN                           Temp;for(Temp = 0; Temp <= 5; Temp++) {DEBUG ((DEBUG_INFO, "n"));}DEBUG ((DEBUG_INFO, "Peim creat hob is start!..n"));DataLength = sizeof(TEST_STR);Status = (*PeiServices)->AllocatePool (PeiServices, DataLength, (VOID **)&Data);ASSERT (!EFI_ERROR (Status));Data->number=123;Data->PrintMesg=PrintMesg;HobData = BuildGuidHob (&gMyFirstHobGuid, DataLength);ASSERT (HobData != NULL);CopyMem (HobData, Data, DataLength);//*NewData = (UINTN)NewBase;/*(*PeiServices)->CreateHob (PeiServices,EFI_HOB_TYPE_MEMORY_ALLOCATION,sizeof (EFI_HOB_MEMORY_ALLOCATION),(VOID **)&Hob);Status = (*PeiServices)->AllocatePool (PeiServices, DataLength, (VOID **)&Data);ASSERT (!EFI_ERROR (Status));Data->number=123;Data->PrintMesg=PrintDxeMesg;Hob->AllocDescriptor.Name = gMyFirstHobGuid;Hob->AllocDescriptor.MemoryBaseAddress = (EFI_MEMORY_TYPE)Data;Hob->AllocDescriptor.MemoryLength = DataLength;Hob->AllocDescriptor.MemoryType = EfiMemoryMappedIO;*/DEBUG ((DEBUG_INFO, "Peim creat hob is end!..n"));return Status;
}

inf文件

PATH:

edk2/EmulatorPkg/TestByMy/PeiTest/MyFirstPeiHob/MyFistHob.inf

code:

## @file
# for creat hob
#
#  
#
#
##[Defines]INF_VERSION                    = 0x00010005BASE_NAME                      = MyFirstHobFILE_GUID                      = 2D6F6B11-9681-8E11-8579-B57DCD006011MODULE_TYPE                    = PEIMVERSION_STRING                 = 1.0ENTRY_POINT                    = MyFirstHobEntry[Sources]MyFirstHob.c[Packages]MdePkg/MdePkg.decMdeModulePkg/MdeModulePkg.decEmulatorPkg/EmulatorPkg.dec[LibraryClasses]PeiServicesTablePointerLibPeiServicesLibHobLibBaseMemoryLibBaseLibPeimEntryPointDebugLibMemoryAllocationLib[Guids]gMyFirstHobGuid[Depex]TRUE

dec文件

把对应使用的gMyFirstHobGuid加入到全局变量
PATH:

edk2/EmulatorPkg/EmulatorPkg.dec

code:

[Guids]gMyFirstHobGuid            = { 0xf2bdaa96, 0x89a5, 0x11db, { 0x87, 0x19, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } }  

dsc文件

加入到编译中
PATH:

edk2/EmulatorPkg/EmulatorPkg.dsc

code:

  ###  PEI Phase modules##EmulatorPkg/TestByMy/PeiTest/MyFirstPeiHob/MyFistHob.inf

fdf文件

加入到fd中
PATH:

edk2/EmulatorPkg/EmulatorPkg.fdf

code:

#
#  PEI Phase modules
#
INF  EmulatorPkg/TestByMy/PeiTest/MyFirstPeiHob/MyFistHob.inf  

LocateGuidHob

c文件

PATH:

edk2/EmulatorPkg/TestByMy/PeiTest/MyLocateMyHob/DxeDriverLocateMyHob.c

code:

#include <Uefi.h>#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/HobLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>#include <PiPei.h>
#include <Guid/MemoryAllocationHob.h>
#include <Pi/PiHob.h>/**This funtion is  printf  str in debug@return status
**/
typedef 
EFI_STATUS 
(EFIAPI * PEI_HOB_MESSG) (VOID);typedef struct {INT32  number;PEI_HOB_MESSG  PrintMesg;
}TEST_STR;extern EFI_GUID gMyFirstHobGuid;EFI_STATUS
EFIAPI
LocateMyHobEntry(IN EFI_HANDLE        ImageHandle,IN EFI_SYSTEM_TABLE  *SystemTable
)
/**a Dxe Drier to locate my hob.@param ImageHandle     Image handle this driver.@param SystemTable     Pointer to SystemTable.@retval EFI_SUCESS     This function always complete successfully.**/
{EFI_STATUS               Status;UINTN                    Temp;TEST_STR                 *PacketHeader;EFI_PEI_HOB_POINTERS      HobPointer;for(Temp = 0; Temp <= 5; Temp++) {DEBUG ((EFI_D_ERROR, "n"));}DEBUG ((DEBUG_INFO, "dxe locate hob is start!..n"));HobPointer.Raw = GetFirstGuidHob (&gMyFirstHobGuid);PacketHeader = (TEST_STR *) GET_GUID_HOB_DATA (HobPointer.Guid);PacketHeader->PrintMesg();/*HobPointer.Raw = GetHobList ();while ((HobPointer.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION,HobPointer.Raw)) != NULL) {if(CompareGuid(&(HobPointer.MemoryAllocation->AllocDescriptor.Name), &gMyFirstHobGuid)){Data = (TEST_STR *)HobPointer.MemoryAllocation->AllocDescriptor.MemoryBaseAddress;DEBUG ((EFI_D_ERROR, "number is:%dn",Data->number));Data->PrintMesg();return EFI_SUCCESS;}HobPointer.Raw = GET_NEXT_HOB (HobPointer);}*/DEBUG ((DEBUG_INFO, "dxe locate hob is end!..n"));Status=EFI_SUCCESS;return Status;
}

inf文件

PATH:

edk2/EmulatorPkg/TestByMy/PeiTest/MyLocateMyHob/DxeDriverLocateMyHob.inf

code:

## @file
#  locate my hob
#
#
#
#
##[Defines]INF_VERSION                    = 0x00010005BASE_NAME                      = LocateMyHobFILE_GUID                      = 69879123-ED74-44db-AE97-1FA5E4ED2116MODULE_TYPE                    = UEFI_DRIVERVERSION_STRING                 = 1.0ENTRY_POINT                    = LocateMyHobEntry[Sources]DxeDriverLocateMyHob.c[Packages]MdePkg/MdePkg.decMdeModulePkg/MdeModulePkg.decEmulatorPkg/EmulatorPkg.dec[LibraryClasses]DebugLibUefiDriverEntryPointBaseLibBaseMemoryLibDevicePathLibUefiBootServicesTableLibMemoryAllocationLibUefiLibHobLib[Guids]gMyFirstHobGuid[Depex]TRUE

dsc文件

PATH:

edk2/EmulatorPkg/EmulatorPkg.dsc

code:

  #  DXE Phase modules###EmulatorPkg/TestByMy/PeiTest/MyLocateMyHob/DxeDriverLocateMyHob.inf

fdf文件

#
#  DXE Phase modules
#
INF  EmulatorPkg/TestByMy/PeiTest/MyLocateMyHob/DxeDriverLocateMyHob.inf

结果

本文发布于:2024-01-28 15:13:46,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17064260298316.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:简单   PEI   hob
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23