Step to UEFI (228)QEMU Setup 首页研究

最近研究了一下 OVMF 项目的 Setup 首页界面,实现的方法挺有意思。

第一个问题,具体代码在什么地方,如果我想增加一行字应该如何实现。

OVMF 运行首页

经过研究,相关代码在  MdeModulePkg\Application\UiApp\FrontPage.c 中。首先,在 FrontPageVfr.Vfr 定义了8个字符串变量,例如:STR_CUSTOMIZE_BANNER_LINE4_LEFT。 在首页上面左右各有4个。在 UpdateFrontPageBannerStrings() 函数中动态填充这些字符串。例如:从 SMBIOS 中取得CPU 信息显示出来:

    if ((Record->Type == SMBIOS_TYPE_PROCESSOR_INFORMATION) && !FoundCpu) {
      Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;
      //
      // The information in the record should be only valid when the CPU Socket is populated.
      //
      if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) {
        StrIndex = Type4Record->ProcessorVersion;
        GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);
        UiCustomizeFrontPageBanner (2, TRUE, &NewString);
        HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NewString, NULL);
        FreePool (NewString);

        ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);
        UiCustomizeFrontPageBanner (2, FALSE, &NewString);
        HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NewString, NULL);
        FreePool (NewString);

        FoundCpu = TRUE;
      }
    }

知道了上面的实现,如果想实现增加一行字符串,实现非常简单:在  FrontPageStrings.uni 文件中修改字符串增加内容即可:

#string STR_CUSTOMIZE_BANNER_LINE4_LEFT  #language en-US  "www.lab-z.com"
                                         #language fr-FR  ""

运行结果:

可以看到上面增加了 www.lab-z.com 字样

第二个问题,研究一下BIOS 版本号的显示。取得的方法非常类似,同样的文件中,代码如下:

    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);
      }
    }

就是说,如果没有定义 PcdFirmwareVersionString 那么会从 SMBIOS 中抓取BIOS 版本显示出来。

在 \OvmfPkg\SmbiosPlatformDxe\SmbiosPlatformDxe.c 可以看到版本信息定义如下:

#define TYPE0_STRINGS \
  "EFI Development Kit II / OVMF\0"     /* Vendor */ \
  "0.0.0\0"                             /* BiosVersion */ \
  "02/06/2015\0"                        /* BiosReleaseDate */

可以通过直接修改上面代码的方式来实现修改版本号的目标。作为“寻常不走路”的有志青年,当然不会满足于使用这样的方式来修改版本号。下面介绍直接在二进制上修改这个版本号。

不走寻常路

在 Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\4110465d-5ff3-4f4b-b580-24ed0d06747aSmbiosPlatformDxe 目录下,可以找到 4110465d-5ff3-4f4b-b580-24ed0d06747a.ffs 这个文件。打开文件可以搜索到 “1.2.3”字样:

可以直接搜索到字符串

尝试修改为 “4.5.6” 之后,再次使用之前介绍过的 GenFds ,生成 FD 文件,运行后就可以发现字符发生了变化:

版本号发生了变化

这个实验也从侧面证明了 GenFds 是将需要的 FFS 文件集合在一起,然后压缩放入指定的文件中。

发表回复

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