EFI基本概念之HOB

1 基本概念及用法

    HOB是Hand-offblock的缩写。是PEI阶段向DXE传递系统信息的手段。PEI阶段构建一些HOB结构,然后将其作为参数传给DXE阶段函数,DXE Core会根据其使用平台相关资源。

    HOB是系列的连续的内存结构体,可以认为其由三部分构成:第一部分,是PHIT头,它描述了HOB的起始地址以及总的内存使用;第二部分是各个Hob列表,DXE阶段会根据这一部分获取上关资源;第三部分是结束部分。

 

1.1 PHIT头:

typedef struct {

 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;

 

1.2 HOB列表中的一个

typedef struct {

 EFI_HOB_GENERIC_HEADER           Header;

 EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor;

} EFI_HOB_MEMORY_ALLOCATION;

 

1.3 EFI_HOB_GENERIC_HEADER

typedef struct {

  UINT16    HobType;

  UINT16    HobLength;

  UINT32    Reserved;

} EFI_HOB_GENERIC_HEADER;

每一个HOB,都有一个HEADER,来指示该HOB的类型。包括PHIT头,也会有HEADER。下面来看一下HOB定义的类型有哪些:

#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_UNUSED               0xFFFE

#define EFI_HOB_TYPE_END_OF_HOB_LIST      0xFFFF

我是从UDK2014上拷贝出来的,不知道最新的PI SPEC有没有增加。当然如果规范没定义,也可以根据需要自己定义,因为自已是生产者自己也是消费者。

 

2. HOB相关函数

2.1创建HOB

EFI_STATUS

EFIAPI

PeiCreateHob (

  IN CONSTEFI_PEI_SERVICES  **PeiServices,

  IN UINT16            Type,

  IN UINT16            Length,

  IN OUT VOID          **Hob

  )

{

Step1. 获取HOB列表的首地址,即PHIT头。

    Step2. 确定是否有足够的空间建立该HOB

    Step3. 找到结束标志的HOB,将其改写成该HOB类型。并将结束标志的HOB移至该HOB下方。

    Step4. 更新PHITHOB

}

在创建该HOB后,我们就可以将该HOB的实际数据填至相应区域内。

 

2.2 获取HobList首地址

EFI_STATUS

EFIAPI

PeiGetHobList (

  IN CONSTEFI_PEI_SERVICES  **PeiServices,

  IN OUT VOID          **HobList

  )

{

    Step1. 如果用来接收HOB的HobList为空,返回非法。

    Step2. 由参数PeiSerivces得到PEI Core实例,进而获得HobList首地址。

}

 

2.3 DXE阶段使用HOB

    HOB的真正使用是在DXE阶段,当然PEI阶段也可以使用,但代码中并没有那么用。DXE阶段使用HOB时,必须先解析其结构。具体如下:

 

 

 

2.3.1 获取HOBList首地址

VOID *

EFIAPI

GetHobList (

  VOID

  )

{

  ASSERT (mHobList!= NULL);

  return mHobList;

}

 

2.3.2 获取给定类型的HOB

VOID *

EFIAPI

GetFirstHob (

  IN UINT16                 Type

  )

{

  VOID      *HobList;

 

  HobList =GetHobList ();

  return GetNextHob(Type, HobList);

}

其中GetNextHob()会根据HOB类型,返回其第一个匹配的HOB。

 

2.3.3 GetNextHob()获取类型匹配的HOB

VOID *

EFIAPI

GetNextHob (

  IN UINT16                 Type,

  IN CONSTVOID             *HobStart

  )

{

    Step1. HobStart不准为空。

    Step2. 将HobStart作为地址,赋值给Hob。

    Step3. 判断其是否是HOB的结尾,如果是,则没找到。否则进入Step4。

Step4. 比较该HOB类型是不是和找的类型一致,如果一致,则将其返回。否则进入Step5。Step5. 找到紧邻该HOB的下一个HOB,继续Step3。

}

 

2.3.4 GET_NEXT_HOB的用法

在2.3.3中,想找到某HOB的下一个HOB,则需要计算当前HOB大小,并且跳过该HOB。这就需要用到GET_NEXT_HOB宏定义。

 

#define GET_NEXT_HOB(HobStart) \

  (VOID *)(*(UINT8**)&(HobStart) + GET_HOB_LENGTH (HobStart))

而GET_HOB_LENTGH的原型为

#define GET_HOB_LENGTH(HobStart) \

 ((*(EFI_HOB_GENERIC_HEADER **)&(HobStart))->HobLength)

所以检索HOB最重要的一个字段是Header的HobLength字段。有了它,我们就可以正确地检索每一个HOB了。

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值