UEFI BIOS 之HOB

HOB的全称是Hand-Off Block,从名字上也可以看出来,它表示的是一种用于交接的数据。按照HOB的使用情况,可以将BIOS的启动阶段分为两个部分:

HOB生成阶段(HOB producer phase),用来创建和修改HOB;

HOB消费阶段(HOB consumer phase),用来使用HOB,注意此阶段HOB是只读的。

手册为了将x86的Platform Initialization扩展到更多的平台,已经不再直接使用PEI、DXE等阶段说明HOB的使用情况,不过对于x86架构的BIOS来说,HOB生成阶段其实就是SEC和PEI阶段,而HOB消费阶段就是DXE和BDS阶段。为了方便,本文还是直接使用PEI、DXE等术语。术语的对应关系如下表所示HOB的构成

HOB在PEI阶段创建,并返回一个列表(称为HOB List,HOB列表),其中的HOB一个个堆叠放置,最终构成如下的形式:

根据HOB中包含的数据的不同可以对HOB进行分类,且HOB列表的第一个必须要是PHIT HOB。PHIT的全称是Phase Handoff Information Table,它是第一个被创建的HOB,对应的指针在PEI的核心数据中:

HOB列表的最后是一个End of HOB,它有特定了类型EFI_HOB_TYPE_END_OF_HOB_LIST,在PHIT HOB中就有一个成员EfiEndOfHobList指向它。

Hob的类型:

//

// 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操作接口都是以这里为基础的,比如EFI_PEI_SERVICES中就有接口GetHobList()

 

创建PHIT HOB的大致流程如下(不同的平台可能会有不同):

Pei和Dxe阶段的HOB传递在代码中的体现为PeiMain中:HobList

TempPtr.DxeIpl->Entry (

                             TempPtr.DxeIpl,

                             &PrivateData.Ps,

                             PrivateData.HobList

                             );

DxeMain中:HobStart

DxeMain (IN  VOID *HobStart)

注意:Dxe阶段只会读取Hob,不会改写Hob;

HOB结构的实现分为三部分,PHIT头,描述Hob的其实位置和内存使用信息;各种Hob的列表,Dxe从该列表上获取资源,传参为Hob Type和guid;最后时Hob结束部分;

第一次进入PeiCore的时候,还是Car阶段,内存没有初始化,InitializeMemoryServices 中调用PeiCoreBuildHobHandoffInfoTable开启HOB创建;位置在Car中;

CAR:Cache As Ram,CPU内缓存当临时memory使用,此时实际的memory未完成初始化;

每一个HOB都包含一个通用的结构:

///

/// Describes the format and size of the data inside the HOB.

/// All HOBs must contain this generic HOB header.

///

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;

通过这个头就能找到下一个Hob 通过比对Hob type解析Hob表,还有一种扩展GUID的hob可以通过匹配Guid来查找hob表,

EFI_HOB_TYPE_GUID_EXTENSION

EFI_HOB_GUID_TYPE;这种类型结构体在hob中加入了guid 作为匹配信息、

HOB在HOB List里是连续创建的,在HOB header(EFI_HOB_GENERIC_HEADER)中描述了HOB的长度和Type,创建后的HOB是不能删除的,否则无法查找下一个HOB。

HOB的长度都是8字节对齐的;

Page是从高地址往低地址分配的,同时要创建一个HOB描述该Page。(调用allocatePages完成的工作)

Top要大于Bottom,否则无资源。

 

typedef enum {

  ///

  /// Not used.

  ///

  EfiReservedMemoryType,

  ///

  /// The code portions of a loaded application.

  /// (Note that UEFI OS loaders are UEFI applications.)

  ///

  EfiLoaderCode,

  ///

  /// The data portions of a loaded application and the default data allocation

  /// type used by an application to allocate pool memory.

  ///

  EfiLoaderData,

  ///

  /// The code portions of a loaded Boot Services Driver.

  ///

  EfiBootServicesCode,

  ///

  /// The data portions of a loaded Boot Serves Driver, and the default data

  /// allocation type used by a Boot Services Driver to allocate pool memory.

  ///

  EfiBootServicesData,

  ///

  /// The code portions of a loaded Runtime Services Driver.

  ///

  EfiRuntimeServicesCode,

  ///

  /// The data portions of a loaded Runtime Services Driver and the default

  /// data allocation type used by a Runtime Services Driver to allocate pool memory.

  ///

  EfiRuntimeServicesData,

  ///

  /// Free (unallocated) memory.

  ///

  EfiConventionalMemory,

  ///

  /// Memory in which errors have been detected.

  ///

  EfiUnusableMemory,

  ///

  /// Memory that holds the ACPI tables.

  ///

  EfiACPIReclaimMemory,

  ///

  /// Address space reserved for use by the firmware.

  ///

  EfiACPIMemoryNVS,

  ///

  /// Used by system firmware to request that a memory-mapped IO region

  /// be mapped by the OS to a virtual address so it can be accessed by EFI runtime services.

  ///

  EfiMemoryMappedIO,

  ///

  /// System memory-mapped IO region that is used to translate memory

  /// cycles to IO cycles by the processor.

  ///

  EfiMemoryMappedIOPortSpace,

  ///

  /// Address space reserved by the firmware for code that is part of the processor.

  ///

  EfiPalCode,

  ///

  /// A memory region that operates as EfiConventionalMemory,

  /// however it happens to also support byte-addressable non-volatility.

  ///

  EfiPersistentMemory,

  ///

  /// A memory region that describes system memory that has not been accepted

  /// by a corresponding call to the underlying isolation architecture.

  ///

  EfiUnacceptedMemoryType,

  EfiMaxMemoryType

} EFI_MEMORY_TYPE;

  /// The code portions of a loaded Boot Services Driver.

  EfiBootServicesCode,  //3

  ///

  /// The data portions of a loaded Boot Serves Driver, and the default data

  /// allocation type used by a Boot Services Driver to allocate pool memory.

  ///

  EfiBootServicesData, //4

EDKii中打印Hob信息:

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只小菜鸟-BIOS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值