【UEFI基础】HOB介绍

您所在的位置:网站首页 bmc是什么的缩写 【UEFI基础】HOB介绍

【UEFI基础】HOB介绍

2023-03-16 13:43| 来源: 网络整理| 查看: 265

综述

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 SpecificationTerm Used in Other PI SpecificationsHOB producer phasePEI phaseHOB consumer phaseDXE phaseexecutable content in the HOB producer phasePre-EFI Initialization Module (PEIM)hand-off into the HOB consumer phaseDXE Initial Program Load (IPL) PEIM orDXE IPL PEIM-to-PEIM Interface (PPI)platform boot-policy phaseBoot 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的大致流程如下(不同的平台可能会有不同):

PeiCore InitializeMemoryServices PeiCoreBuildHobHandoffInfoTable

在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()创建,对应的流程:

PeiCore PeiDispatcher PeiCheckAndSwitchStack 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入口,创建的流程:

DxeLoadCore BuildModuleHob

对应的代码:

// // 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, &DxeCoreEntryPoint, &AuthenticationState ); } while (EFI_ERROR (Status)); // // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name. // Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo); ASSERT_EFI_ERROR (Status); // // Add HOB for the DXE Core // BuildModuleHob ( &DxeCoreFileInfo.FileName, DxeCoreAddress, ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE), DxeCoreEntryPoint );

BuildModuleHob()的核心代码:

CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid); Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule; Hob->MemoryAllocationHeader.MemoryLength = ModuleLength; Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;

可以看到代码其实就是从FV中获取DXE核心入口,并根据它的值创建HOB,根据它可以创建DXE核心的Image Hand了,对应的操作位于函数CoreInitializeImageServices():

// 获取EFI_HOB_MEMORY_ALLOCATION_MODULE这个HOB DxeCoreHob.Raw = HobStart; while ((DxeCoreHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw)) != NULL) { if (CompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) { // // Find Dxe Core HOB // break; } DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob); } // 获取到DxeCoreEntryPoint DxeCoreImageBaseAddress = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress; DxeCoreImageLength = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength; DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreHob.MemoryAllocationModule->EntryPoint; gDxeCoreFileName = &DxeCoreHob.MemoryAllocationModule->ModuleName; // 安装Image Handle Image = &mCorePrivateImage; Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)DxeCoreEntryPoint; Image->ImageBasePage = DxeCoreImageBaseAddress; Image->NumberOfPages = (UINTN)(EFI_SIZE_TO_PAGES ((UINTN)(DxeCoreImageLength))); Image->Tpl = gEfiCurrentTpl; Image->Info.SystemTable = gDxeCoreST; Image->Info.ImageBase = (VOID *)(UINTN)DxeCoreImageBaseAddress; Image->Info.ImageSize = DxeCoreImageLength; // // Install the protocol interfaces for this image // Status = CoreInstallProtocolInterface ( &Image->Handle, &gEfiLoadedImageProtocolGuid, EFI_NATIVE_INTERFACE, &Image->Info ); ASSERT_EFI_ERROR (Status); Resource Descriptor HOB

该HOB定义物理内存的属性,其结构:

/// /// Describes the resource properties of all fixed, /// nonrelocatable resource ranges found on the processor /// host bus during the HOB producer phase. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_RESOURCE_DESCRIPTOR. /// EFI_HOB_GENERIC_HEADER Header; /// /// A GUID representing the owner of the resource. This GUID is used by HOB /// consumer phase components to correlate device ownership of a resource. /// EFI_GUID Owner; /// /// The resource type enumeration as defined by EFI_RESOURCE_TYPE. /// EFI_RESOURCE_TYPE ResourceType; /// /// Resource attributes as defined by EFI_RESOURCE_ATTRIBUTE_TYPE. /// EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute; /// /// The physical start address of the resource region. /// EFI_PHYSICAL_ADDRESS PhysicalStart; /// /// The number of bytes of the resource region. /// UINT64 ResourceLength; } EFI_HOB_RESOURCE_DESCRIPTOR;

这样的HOB一般有很多个,它们通过BuildResourceDescriptorHob()函数创建:

/** Builds a HOB that describes a chunk of system memory. This function builds a HOB that describes a chunk of system memory. If there is no additional space for HOB creation, then ASSERT(). @param ResourceType The type of resource described by this HOB. @param ResourceAttribute The resource attributes of the memory described by this HOB. @param PhysicalStart The 64 bit physical address of memory described by this HOB. @param NumberOfBytes The length of the memory described by this HOB in bytes. **/ VOID EFIAPI BuildResourceDescriptorHob ( IN EFI_RESOURCE_TYPE ResourceType, IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute, IN EFI_PHYSICAL_ADDRESS PhysicalStart, IN UINT64 NumberOfBytes ) { EFI_HOB_RESOURCE_DESCRIPTOR *Hob; Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)); ASSERT (Hob != NULL); Hob->ResourceType = ResourceType; Hob->ResourceAttribute = ResourceAttribute; Hob->PhysicalStart = PhysicalStart; Hob->ResourceLength = NumberOfBytes; }

该HOB包含的类型:

// // Value of ResourceType in EFI_HOB_RESOURCE_DESCRIPTOR. // #define EFI_RESOURCE_SYSTEM_MEMORY 0x00000000 #define EFI_RESOURCE_MEMORY_MAPPED_IO 0x00000001 #define EFI_RESOURCE_IO 0x00000002 #define EFI_RESOURCE_FIRMWARE_DEVICE 0x00000003 #define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT 0x00000004 #define EFI_RESOURCE_MEMORY_RESERVED 0x00000005 #define EFI_RESOURCE_IO_RESERVED 0x00000006 // // BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED is defined for unaccepted memory. // But this defitinion has not been officially in the PI spec. Base // on the code-first we define BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED at // MdeModulePkg/Include/Pi/PrePiHob.h and update EFI_RESOURCE_MAX_MEMORY_TYPE // to 8. After BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED is officially published // in PI spec, we will re-visit here. // // #define BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED 0x00000007 #define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000008

包含的属性:

// // These types can be ORed together as needed. // // The following attributes are used to describe settings // #define EFI_RESOURCE_ATTRIBUTE_PRESENT 0x00000001 #define EFI_RESOURCE_ATTRIBUTE_INITIALIZED 0x00000002 #define EFI_RESOURCE_ATTRIBUTE_TESTED 0x00000004 #define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED 0x00000080 // // This is typically used as memory cacheability attribute today. // NOTE: Since PI spec 1.4, please use EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED // as Physical write protected attribute, and EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED // means Memory cacheability attribute: The memory supports being programmed with // a writeprotected cacheable attribute. // #define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED 0x00000100 #define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED 0x00000200 #define EFI_RESOURCE_ATTRIBUTE_PERSISTENT 0x00800000 // // The rest of the attributes are used to describe capabilities // #define EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC 0x00000008 #define EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC 0x00000010 #define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 0x00000020 #define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 0x00000040 #define EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE 0x00000400 #define EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE 0x00000800 #define EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE 0x00001000 #define EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE 0x00002000 #define EFI_RESOURCE_ATTRIBUTE_16_BIT_IO 0x00004000 #define EFI_RESOURCE_ATTRIBUTE_32_BIT_IO 0x00008000 #define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO 0x00010000 #define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED 0x00020000 #define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE 0x00100000 // // This is typically used as memory cacheability attribute today. // NOTE: Since PI spec 1.4, please use EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE // as Memory capability attribute: The memory supports being protected from processor // writes, and EFI_RESOURCE_ATTRIBUTE_WRITE_PROTEC TABLE means Memory cacheability attribute: // The memory supports being programmed with a writeprotected cacheable attribute. // #define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE 0x00200000 #define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE 0x00400000 #define EFI_RESOURCE_ATTRIBUTE_PERSISTABLE 0x01000000 #define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED 0x00040000 #define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE 0x00080000 // // Physical memory relative reliability attribute. This // memory provides higher reliability relative to other // memory in the system. If all memory has the same // reliability, then this bit is not used. // #define EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE 0x02000000

在内存初始化完成之后,会调用该接口来定义内存的属性,比如:

// // Report first 640KB of memory // BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, MEM_TESTED_ATTR, (EFI_PHYSICAL_ADDRESS) (0), (UINT64) (0xA0000) ); // // Report first 0A0000h - 0FFFFFh as RESERVED memory // BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_RESERVED, MEM_TESTED_ATTR, (EFI_PHYSICAL_ADDRESS) (0xA0000), (UINT64) (0x60000) ); // // Report first 0x100000 - FSP reserved memory as system memory // BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, MEM_TESTED_ATTR, (EFI_PHYSICAL_ADDRESS) (0x100000), (UINT64) (PeiMemBase - 0x100000) );

在DXE阶段会收集这些HOB并初始化GDC(Global Coherency Domain)映射表。

GUID Extension HOB

该HOB术语自定义类型,如果我们需要自己创建从PEI阶段到DXE阶段传递数据的HOB,就可以使用这种类型,这也是BIOS开发时最可能用到的HOB,其结构体:

/// /// Allows writers of executable content in the HOB producer phase to /// maintain and manage HOBs with specific GUID. /// typedef struct { /// /// The HOB generic header. Header.HobType = EFI_HOB_TYPE_GUID_EXTENSION. /// EFI_HOB_GENERIC_HEADER Header; /// /// A GUID that defines the contents of this HOB. /// EFI_GUID Name; // // Guid specific data goes here // } EFI_HOB_GUID_TYPE;

它是一个不定长的结构体,Name之后还可以有自定义的数据。这个的Name是一个唯一的GUID,后续DXE阶段通过该GUID来找到自定义的数据。

下面是一个示例,首选是HOB的创建,它位于PEI阶段,对应代码模块BeniPkg\Pei\HobProvider\HobProvider.inf:

EFI_STATUS EFIAPI HobProviderEntry ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { BENI_HOB_DATA *Hob = NULL; UINT8 Index = 0; DEBUG ((EFI_D_ERROR, "Creating HOB ...\n")); Hob = BuildGuidHob (&gBeniHobGuid, sizeof (BENI_HOB_DATA)); if (NULL == Hob) { DEBUG ((EFI_D_ERROR, "[%a][%d] BuildGuidHob failed.\n", __FUNCTION__, __LINE__)); return EFI_OUT_OF_RESOURCES; } for (Index = 0; Index EFI_PEI_HOB_POINTERS Hob; UINTN Index = 0; UINT8 *Data = NULL; Hob.Raw = GetFirstGuidHob (&gBeniHobGuid); if (NULL == Hob.Raw) { DEBUG ((EFI_D_ERROR, "[%a][%d] Failed. - %r\n", __FUNCTION__, __LINE__, EFI_NOT_FOUND)); return EFI_NOT_FOUND; } Data = (UINT8 *)(GET_GUID_HOB_DATA (Hob.Raw)); DEBUG ((EFI_D_ERROR, "BENI Hob data:\n")); for (Index = 0; Index


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3