UEFI基础HOB介绍
Posted jiangwei0512
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UEFI基础HOB介绍相关的知识,希望对你有一定的参考价值。
综述
HOB的全称是Hand-Off Block,从名字上也可以看出来,它表示的是一种用于交接的数据。按照HOB的使用情况,可以将Bios的启动阶段分为两个部分:
- HOB生成阶段(HOB producer phase),用来创建和修改HOB;
- HOB消费阶段(HOB consumer phase),用来使用HOB,注意此阶段HOB是只读的。
而这里说的“交接”就是从HOB生成阶段像HOB消费阶段交接数据,至于交接的是什么数据,后面会一一介绍。
本文参考《PI_Spec_1_7_A_final_May1.pdf》(后面统称为PI规范),该手册为了将x86的Platform Initialization扩展到更多的平台,已经不再直接使用PEI、DXE等阶段说明HOB的使用情况,不过对于x86架构的BIOS来说,HOB生成阶段其实就是SEC和PEI阶段,而HOB消费阶段就是DXE和BDS阶段。为了方便,本文还是直接使用PEI、DXE等术语。术语的对应关系如下表所示:
Term Used in the HOB Specification | Term Used in Other PI Specifications |
---|---|
HOB producer phase | PEI phase |
HOB consumer phase | DXE phase |
executable content in the HOB producer phase | Pre-EFI Initialization Module (PEIM) |
hand-off into the HOB consumer phase | DXE Initial Program Load (IPL) PEIM or DXE IPL PEIM-to-PEIM Interface (PPI) |
platform boot-policy phase | Boot Device Selection (BDS) phase |
注意,虽然上表中只有PEI和DXE,但是从实际的情况来看,SEC和BDS也分别可以作为HOB生成阶段和HOB消费阶段。
HOB的构成
HOB在PEI阶段创建,并返回一个列表(称为HOB List,HOB列表),其中的HOB一个个堆叠放置,最终构成如下的形式:
根据HOB中包含的数据的不同可以对HOB进行分类,且HOB列表的第一个必须要是PHIT HOB。PHIT的全称是Phase Handoff Information Table,它是第一个被创建的HOB,对应的指针在PEI的核心数据中:
///
/// Union of all the possible HOB Types.
///
typedef union
EFI_HOB_GENERIC_HEADER *Header;
EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable;
EFI_HOB_MEMORY_ALLOCATION *MemoryAllocation;
EFI_HOB_MEMORY_ALLOCATION_BSP_STORE *MemoryAllocationBspStore;
EFI_HOB_MEMORY_ALLOCATION_STACK *MemoryAllocationStack;
EFI_HOB_MEMORY_ALLOCATION_MODULE *MemoryAllocationModule;
EFI_HOB_RESOURCE_DESCRIPTOR *ResourceDescriptor;
EFI_HOB_GUID_TYPE *Guid;
EFI_HOB_FIRMWARE_VOLUME *FirmwareVolume;
EFI_HOB_FIRMWARE_VOLUME2 *FirmwareVolume2;
EFI_HOB_FIRMWARE_VOLUME3 *FirmwareVolume3;
EFI_HOB_CPU *Cpu;
EFI_HOB_MEMORY_POOL *Pool;
EFI_HOB_UEFI_CAPSULE *Capsule;
UINT8 *Raw;
EFI_PEI_HOB_POINTERS;
///
/// Forward declaration for PEI_CORE_INSTANCE
///
typedef struct _PEI_CORE_INSTANCE PEI_CORE_INSTANCE;
///
/// Pei Core private data structure instance
///
struct _PEI_CORE_INSTANCE
UINTN Signature;
///
/// Point to ServiceTableShadow
///
EFI_PEI_SERVICES *Ps;
PEI_PPI_DATABASE PpiData;
/// 其它略。下面就是指向第一个HOB的指针,EFI_PEI_HOB_POINTERS是一个Union,包括各种指针:
EFI_PEI_HOB_POINTERS HobList;
后面的HOB操作接口都是以这里为基础的,比如EFI_PEI_SERVICES
中就有接口GetHobList()
,其实现:
///
/// Pei Core Instance Data Macros
///
#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \\
CR(a, PEI_CORE_INSTANCE, Ps, PEI_CORE_HANDLE_SIGNATURE)
EFI_STATUS
EFIAPI
PeiGetHobList (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN OUT VOID **HobList
)
PEI_CORE_INSTANCE *PrivateData;
//
// Only check this parameter in debug mode
//
DEBUG_CODE_BEGIN ();
if (HobList == NULL)
return EFI_INVALID_PARAMETER;
DEBUG_CODE_END ();
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
*HobList = PrivateData->HobList.Raw;
return EFI_SUCCESS;
创建PHIT HOB的大致流程如下(不同的平台可能会有不同):
在PeiCoreBuildHobHandoffInfoTable()
函数中有PHIT HOB的初始化:
EFI_STATUS
PeiCoreBuildHobHandoffInfoTable (
IN EFI_BOOT_MODE BootMode,
IN EFI_PHYSICAL_ADDRESS MemoryBegin,
IN UINT64 MemoryLength
)
EFI_HOB_HANDOFF_INFO_TABLE *Hob;
EFI_HOB_GENERIC_HEADER *HobEnd;
Hob = (VOID *)(UINTN)MemoryBegin;
HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
Hob->Header.HobLength = (UINT16)sizeof (EFI_HOB_HANDOFF_INFO_TABLE);
Hob->Header.Reserved = 0;
HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
HobEnd->HobLength = (UINT16)sizeof (EFI_HOB_GENERIC_HEADER);
HobEnd->Reserved = 0;
Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
Hob->BootMode = BootMode;
Hob->EfiMemoryTop = MemoryBegin + MemoryLength;
Hob->EfiMemoryBottom = MemoryBegin;
Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength;
Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd + 1);
Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
return EFI_SUCCESS;
这里的数据可以跟前面的图对应。有了第一个HOB,之后的HOB就在此基础之上堆叠,最终完成所有需要的HOB。下面介绍目前PI规范中定义的HOB分类。
HOB分类
当前PI规范定义的HOB有如下的几种类型:
每一个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的类型HobType
:
//
// 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的长度HobLength
,通过它就可以知道下一个HOB的位置。
下面介绍一些常用的HOB。
PHIT HOB
前面已经介绍了PHIT HOB,它的结构体如下:
///
/// Contains general state information used by the HOB producer phase.
/// This HOB must be the first one in the HOB list.
///
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;
里面主要有包含两个部分,一个用来描述启动模式,另一个用来描述HOB内存的分布,这个也已经在前文的图中说明。
Memory Allocation HOB
PHIT HOB之后是Memory Allocation HOB,它对应结构体:
///
/// Describes all memory ranges used during the HOB producer
/// phase that exist outside the HOB list. This HOB type
/// describes how memory is used, not the physical attributes of memory.
///
typedef struct
///
/// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION.
///
EFI_HOB_GENERIC_HEADER Header;
///
/// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the
/// various attributes of the logical memory allocation.
///
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor;
//
// Additional data pertaining to the "Name" Guid memory
// may go here.
//
EFI_HOB_MEMORY_ALLOCATION;
EFI_HOB_MEMORY_ALLOCATION_HEADER
结构体的构成:
///
/// EFI_HOB_MEMORY_ALLOCATION_HEADER describes the
/// various attributes of the logical memory allocation. The type field will be used for
/// subsequent inclusion in the UEFI memory map.
///
typedef struct
///
/// A GUID that defines the memory allocation region's type and purpose, as well as
/// other fields within the memory allocation HOB. This GUID is used to define the
/// additional data within the HOB that may be present for the memory allocation HOB.
/// Type EFI_GUID is defined in InstallProtocolInterface() in the UEFI 2.0
/// specification.
///
EFI_GUID Name;
///
/// The base address of memory allocated by this HOB. Type
/// EFI_PHYSICAL_ADDRESS is defined in AllocatePages() in the UEFI 2.0
/// specification.
///
EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
///
/// The length in bytes of memory allocated by this HOB.
///
UINT64 MemoryLength;
///
/// Defines the type of memory allocated by this HOB. The memory type definition
/// follows the EFI_MEMORY_TYPE definition. Type EFI_MEMORY_TYPE is defined
/// in AllocatePages() in the UEFI 2.0 specification.
///
EFI_MEMORY_TYPE MemoryType;
///
/// Padding for Itanium processor family
///
UINT8 Reserved[4];
EFI_HOB_MEMORY_ALLOCATION_HEADER;
这里也有一个MemoryType
表示类型,这里指的是UEFI下的内存使用类型,比如存放Boot Service的代码和数据的内存类型,Runtime的代码和数据的内存类型,等等。它们有如下的可选值:
///
/// Enumeration of memory types introduced in UEFI.
///
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;
此外,还有几个特别的EFI_HOB_MEMORY_ALLOCATION
:
EFI_HOB_MEMORY_ALLOCATION_STACK
///
/// Describes the memory stack that is produced by the HOB producer
/// phase and upon which all post-memory-installed executable
/// content in the HOB producer phase is executing.
///
typedef struct
///
/// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION.
///
EFI_HOB_GENERIC_HEADER Header;
///
/// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the
/// various attributes of the logical memory allocation.
///
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor;
EFI_HOB_MEMORY_ALLOCATION_STACK;
从名称可以看出来它描述的是BSP执行所需的堆对应内存,通过BuildStackHob()
创建,对应的流程:
函数实现的主要代码:
CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
Hob->AllocDescriptor.MemoryLength = Length;
Hob->AllocDescriptor.MemoryType = EfiBootServicesData;
DXE阶段会进一步的使用该HOB。
EFI_HOB_MEMORY_ALLOCATION_BSP_STORE
///
/// Defines the location of the boot-strap
/// processor (BSP) BSPStore ("Backing Store Pointer Store").
/// This HOB is valid for the Itanium processor family only
/// register overflow store.
///
typedef struct
///
/// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION.
///
EFI_HOB_GENERIC_HEADER Header;
///
/// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the
/// various attributes of the logical memory allocation.
///
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor;
EFI_HOB_MEMORY_ALLOCATION_BSP_STORE;
该HOB主要在Itanium平台的CPU上使用,这里就不再说明。
EFI_HOB_MEMORY_ALLOCATION_MODULE
///
/// Defines the location and entry point of the HOB consumer phase.
///
typedef struct
///
/// The HOB generic header. Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION.
///
EFI_HOB_GENERIC_HEADER Header;
///
/// An instance of the EFI_HOB_MEMORY_ALLOCATION_HEADER that describes the
/// various attributes of the logical memory allocation.
///
EFI_HOB_MEMORY_ALLOCATION_HEADER MemoryAllocationHeader;
///
/// The GUID specifying the values of the firmware file system name
/// that contains the HOB consumer phase component.
///
EFI_GUID ModuleName;
///
/// The address of the memory-mapped firmware volume
/// that contains the HOB consumer phase firmware file.
///
EFI_PHYSICAL_ADDRESS EntryPoint;
EFI_HOB_MEMORY_ALLOCATION_MODULE;
它描述的其实是DXE入口,创建的流程:
对应的代码:
//
// Load the DXE Core from a Firmware Volume.
//
Instance = 0;
do
Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **)&LoadFile);
//
// These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully.
//
ASSERT_EFI_ERROR (Status);
Status = LoadFile->LoadFile (
LoadFile,
FileHandle,
&DxeCoreAddress,
&DxeCoreSize,
以上是关于UEFI基础HOB介绍的主要内容,如果未能解决你的问题,请参考以下文章