最近研究了一下 OVMF 项目的 Setup 首页界面,实现的方法挺有意思。
第一个问题,具体代码在什么地方,如果我想增加一行字应该如何实现。

经过研究,相关代码在 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 ""
运行结果:

第二个问题,研究一下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 文件集合在一起,然后压缩放入指定的文件中。
版主您好:
我使用Intel在github上提供的”Lab_Material_FW”,練習UEFI Driver。連結如下:https://github.com/tianocore-training/Lab_Material_FW/blob/main/FW/LabSampleCode/MyWizardDriver/MyPkg/MyWizardDriver/MyWizardDriver.c
這個MyWizardDriver在Qemu下執行時,進入setup選單內時會被安裝到Device Manager的目錄下,想請教版主為什麼它會自動被安裝在Device Manager的目錄下呢? 謝謝
不好意思,这个没研究过。你可以看看是不是代码中有Device Manager相关的 GUID?