UEFI 基础教程 (七) - HOB 简单使用

一、 编写源代码
  1. 编写UEFI PEI 驱动
    代码C:\edkii\OvmfPkg\MyHelloWorldPEIMHob\MyHelloWorldPEIMHob.c,

    EFI_GUID gMyHelloWorldPEIGUID = { 0xbdb38129, 0x4d65, 0x39f4, { 0x72, 0x12, 0x68, 0xcf, 0x5a, 0x19, 0xa, 0xf8 }};
    
    EFI_STATUS
    EFIAPI
    MyHelloWorldPEIMHobEntry(
      IN       EFI_PEI_FILE_HANDLE  FileHandle,
      IN CONST EFI_PEI_SERVICES     **PeiServices
    )
    { 
      EFI_STATUS                              Status = EFI_SUCCESS;
      DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] MyHelloWorldPEIMHobEntry Start..\n"));
      
      CHAR8  *Hob = NULL;
    
      PeiServices = GetPeiServicesTablePointer();
      Status = PeiServicesCreateHob (
                               EFI_HOB_TYPE_MEMORY_ALLOCATION,
                               64,
                               &Hob
                               );
    
      CHAR8 *HobEnd = (Hob + sizeof (EFI_HOB_GENERIC_HEADER));
      EfiCommonLibCopyMem(HobEnd, &gMyHelloWorldPEIGUID, sizeof(gMyHelloWorldPEIGUID));
      CHAR16 StrHob[] = L"CSDN HOB Data ...";
      // EfiCommonLibCopyMem(HobEnd+16,StrHob,2*MyStrlen(StrHob,128));
      EfiCommonLibCopyMem(HobEnd+16,StrHob,2*17);
      
      DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] MyHelloWorldPEIMHobEntry End..\n"));
      return Status;
    }
    
  2. 编写UEFI DXE 驱动
    代码C:\edkii\OvmfPkg\MyHelloWorldDXEHob\MyHelloWorldDXEHob.c,

    EFI_GUID gMyHelloWorldPEIGUID = { 0xbdb38129, 0x4d65, 0x39f4, { 0x72, 0x12, 0x68, 0xcf, 0x5a, 0x19, 0xa, 0xf8 }};
    
    EFI_STATUS
    EFIAPI
    MyHelloWorldDXEHobEntry(
      IN EFI_HANDLE        ImageHandle,
      IN EFI_SYSTEM_TABLE  *SystemTable
    )
    { 
      EFI_STATUS                              Status = EFI_SUCCESS;
      DEBUG ((EFI_D_ERROR , "[MyHelloWorldHob] MyHelloWorldDXEHobEntry Start..\n"));
      
      EFI_PEI_HOB_POINTERS            Hob;
      UINT8 *HobEnd = NULL;
      Hob.Raw   = GetHobList();
      while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
        //
        // Compare FileGuid both.
        //
        if (CompareGuid (&gMyHelloWorldPEIGUID, &Hob.MemoryAllocation->AllocDescriptor.Name) ) {
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] MyHelloWorldDXEHobEntry  Guid:0x%x\n",Hob.MemoryAllocation->AllocDescriptor.Name.Data1));
          HobEnd = (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + 16);
          DEBUG ((EFI_D_ERROR, "[MyHelloWorldHob] MyHelloWorldDXEHobEntry content:%s\n", (CHAR16 *)HobEnd));
          return EFI_SUCCESS;
        }
        Hob.Raw = GET_NEXT_HOB (Hob);
      }  
      DEBUG ((EFI_D_ERROR , "[MyHelloWorldHob] MyHelloWorldDXEHobEntry End..\n"));
      return Status;
    }
    
二、 编译生成EFI文件

运行edksetup.bat编译整个OvmfPkg Package

三、 运行 DXE Driver MyHelloWorldDXEHob与PEI Driver MyHelloWorldPEIMHob
  1. 拷贝 C:\edkii\Build\OvmfX64\DEBUG_VS2013x86\FV\OVMF.fdC:\qemu
  2. 执行 setup-qemu-x64.bat | findstr MyHelloWorldHob , 然后在UEFI SHELL 中执行 MyHelloWorldAppProtocol.efi,结果如下,
    在这里插入图片描述
  3. 如果需要dump所有的PEI阶段创建的Hob,可以使用以下code
  Hob.Raw = GetHobList ();
  for (; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
    DEBUG((DEBUG_ERROR, "[Csdn] Guid:%g Type:0x%x Length:%x\n",
        Hob.Guid,
        Hob.Header->HobType,
        Hob.Header->HobLength
    ));
  }

在这里插入图片描述

四、 小结

UEFI提供了HOB(Hand-Off-Block)机制,即在PEI阶段将数据打包成数据块存放在一段连续的内存中,数据块的标识为GUID,DXE阶段可以通过该GUID在HOB中找到对应数据块。

HOB 是非常重要数据结构,在CAR时期将会初始化好,UEFI的早期的堆栈都基于HOB,
PEI Phase会创建大量的HOB,包含板级数据(UBA), silicon Hob(Memmap, RC resource),Setup,当进入PEI PostMem phase后,CAR里的HOB会shadown到Mem, 当进入DXE(调用TempPtr.DxeIpl->Entry)后,
这些HOB会被DXE driver大量采用, 用来创建Protocol或者其他初始化。

注意:
HOB 在PEI阶段会被修改,在DXE和SMM中会被使用,原则上不推介SMM修改HOB。创建的单个HOB
Size最大为64K(ASSERT (DataLength <= (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE))); // Make sure that data length is not too long.),需要大数据量的HOB需要注意。
HOB 创建的接口除了上文还有如下通用做法,

Opt1:
MyHelloWorldPtr = AllocateZeroPool (TableLength);
(HELLOWROD_HOB *)MyHelloWorldPtr->xxx = xxx;
...
BuildGuidDataHob (&gMyHelloWorldPEIGUID, MyHelloWorldPtr, TotalLength);

Opt2:
MyHelloWorldPtr = BuildGuidHob (&mVpdBinHobGuid, TotalLength);
(HELLOWROD_HOB *)MyHelloWorldPtr->xxx = xxx;

Hob DEMO源码

  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值