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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 文件中加入下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
!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 加入下面这样一行:

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

再次编译,在

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

1
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 可以看到下面的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
;   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.http://www.lab-z.com/qemusetup/ QEMU Setup 首页研究

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

发表回复

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