Step to UEFI (229)继续研究修改QEMU 显示的版本号

前面提到过 OVMF 的 Setup 首页版本号显示的代码【参考1】,在 \MdeModulePkg\Application\UiApp\FrontPage.c

  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
  while (!EFI_ERROR(Status)) {
    if (Record->Type == SMBIOS_TYPE_BIOS_INFORMATION) {
      Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;
      StrIndex = Type0Record->BiosVersion;
      GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);

      FirmwareVersionString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
      if (*FirmwareVersionString != 0x0000 ) {
        FreePool (NewString);
        NewString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
        UiCustomizeFrontPageBanner (3, TRUE, &NewString);
        HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
      } else {
        UiCustomizeFrontPageBanner (3, TRUE, &NewString);
        HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
        FreePool (NewString);
      }
    }

就是说出了从 SMBIOS 之外,还可以在 PCD 中直接给定。实验,在\OvmfPkg\OvmfPkgX64.dsc 文件中加入下面的代码

!if $(SMM_REQUIRE) == TRUE
  gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire|TRUE
  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
!endif

[PcdsFixedAtBuild]
#LABZ_Start
  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"Galileo 1.0.4"  
#LABZ_End

  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported|6

编译之后,运行结果如下,可以看到新增加了  “Galileo 1.0.4”字样。

新加入了版本字符

但是,非常奇怪的是按照之前的方法,无法在 FFS 文件中找到对应的字符串。为了进一步研究,打开生成 COD 的功能。在 \MdeModulePkg\Application\UiApp\UiApp.inf 加入下面这样一行:

[BuildOptions]  
  MSFT:*_*_X64_CC_FLAGS = /FAsc /Od

再次编译,在

\Build\OvmfX64\DEBUG_VS2015x86\X64\MdeModulePkg\Application\UiApp\UiApp\DEBUG\AutoGen.c 有如下定义:

GLOBAL_REMOVE_IF_UNREFERENCED const UINT16 _gPcd_FixedAtBuild_PcdFirmwareVersionString[14] = {71, 97, 108, 105, 108, 101, 111, 32, 49, 46, 48, 46, 52, 0 };

进一步,在 \Build\OvmfX64\DEBUG_VS2015x86\X64\MdeModulePkg\Application\UiApp\UiApp\AutoGen.cod 可以看到下面的定义

;	COMDAT _gPcd_FixedAtBuild_PcdFirmwareVersionString
CONST	SEGMENT
_gPcd_FixedAtBuild_PcdFirmwareVersionString DW 047H
	DW	061H
	DW	06cH
	DW	069H
	DW	06cH
	DW	065H
	DW	06fH
	DW	020H
	DW	031H
	DW	02eH
	DW	030H
	DW	02eH
	DW	034H
	DW	00H
CONST	ENDS

特别注意,每一个字符是 2Bytes,因此,就是说和之前不同,这里字符串使用的是 Unicode 编码方式。因此,一个字符会使用2个Bytes来进行保存。再次到 FFS 中搜索,可以看到如下字样:

十六进制编辑器直接编辑 Unicode 字符

尝试修改之,然后用前面直接运行 GenFDS 的方法产生的 ROM 文件,运行结果如下:

修修改QEMU Setup 界面之后的结果

进一步研究,在【参考2】有介绍,我们定义的gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString 是 FixedAtBuild PCD的PCD 变量,编译时会像宏一样直接展开放在代码中。

参考:

1.https://www.lab-z.com/qemusetup/ QEMU Setup 首页研究

2. https://blog.csdn.net/jiangwei0512/article/details/80288001 BIOS/UEFI基础——PCD

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注