【UEFI实战】HII之涉及模块
模块
HII的交互逻辑如下图所示:

其中上边是输入设备,比如键盘、鼠标等;右边是输出设备,比如显示器;左边是UEFI变量,用来存放HII会涉及到的数据。这三个部分都属于UEFI基础,不是这里介绍的对象,这里主要说明中间紫色部分的IFR Browser和HII Database,它们也是HII需要关注的重要模块,对应到代码中主要有如下的几个模块:
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
除此之外,其它的模块(就是上图绿色部分Driver)也会提供用户交互界面需要的元素,这通常是为了完成该模块需要的操作。
在上面的三个模块中,HiiDatabaseDxe.inf模块用来初始化并安装操作界面元素的Protocol以及配置相关的Protocol,这些界面元素包括字体,字符串,结构、图像等。SetupBrowserDxe.inf这个模块依赖于HiiDatabaseDxe.inf,它提供了上图中间部分的实现,实际上是整个用户交互界面的引擎,用来实现各类必要的操作(实际上也不是它来实现,它只是调用了在绿色部分Driver中的操作)。DisplayEngineDxe.inf是配合SetupBrowserDxe.inf一起使用的,它依赖于后者。
模块安装的Protocol有如下一些:

HiiDatabaseDxe.inf
本模块初始化了HII_DATABASE_PRIVATE_DATA(对应变量mPrivate):
InitializeListHead (&mPrivate.DatabaseList);InitializeListHead (&mPrivate.DatabaseNotifyList);InitializeListHead (&mPrivate.HiiHandleList);InitializeListHead (&mPrivate.FontInfoList);
然后安装了一堆Protocol:
Status = gBS->InstallMultipleProtocolInterfaces (&Handle,&gEfiHiiFontProtocolGuid,&mPrivate.HiiFont,&gEfiHiiStringProtocolGuid,&mPrivate.HiiString,&gEfiHiiDatabaseProtocolGuid,&mPrivate.HiiDatabase,&gEfiHiiConfigRoutingProtocolGuid,&mPrivate.ConfigRouting,&gEfiConfigKeywordHandlerProtocolGuid,&mPrivate.ConfigKeywordHandler,NULL);
还有一部分是可选的:
if (FeaturePcdGet (PcdSupportHiiImageProtocol)) {Status = gBS->InstallMultipleProtocolInterfaces (&Handle,&gEfiHiiImageProtocolGuid, &mPrivate.HiiImage,&gEfiHiiImageExProtocolGuid, &mPrivate.HiiImageEx,NULL);}
关于各个安装的Protocol,后续会介绍。这些Protocol都安装到了前面提到的HII_DATABASE_PRIVATE_DATA结构体:
typedef struct _HII_DATABASE_PRIVATE_DATA {UINTN Signature;LIST_ENTRY DatabaseList;LIST_ENTRY DatabaseNotifyList;EFI_HII_FONT_PROTOCOL HiiFont;EFI_HII_IMAGE_PROTOCOL HiiImage;EFI_HII_IMAGE_EX_PROTOCOL HiiImageEx;EFI_HII_STRING_PROTOCOL HiiString;EFI_HII_DATABASE_PROTOCOL HiiDatabase;EFI_HII_CONFIG_ROUTING_PROTOCOL ConfigRouting;EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL ConfigKeywordHandler;LIST_ENTRY HiiHandleList;INTN HiiHandleCount;LIST_ENTRY FontInfoList; // global font info listUINTN Attribute; // default system colorEFI_GUID CurrentLayoutGuid;EFI_HII_KEYBOARD_LAYOUT *CurrentLayout;
} HII_DATABASE_PRIVATE_DATA;
这些Protocol就是用来操作UEFI交互界面中的字体、字符串、图像等元素的。
SetupBrowserDxe.inf
该模块依赖于在HiiDatabaseDxe.inf中安装的某些Protocol,所以现有LocateProtocol()操作:
//// Locate required Hii relative protocols//Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid,NULL,(VOID **) &mHiiDatabase);ASSERT_EFI_ERROR (Status);Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid,NULL,(VOID **) &mHiiConfigRouting);ASSERT_EFI_ERROR (Status);Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid,NULL,(VOID **) &mPathFromText);
然后安装Protocol:
//// Install FormBrowser2 protocol//mPrivateData.Handle = NULL;Status = gBS->InstallProtocolInterface (&mPrivateData.Handle,&gEfiFormBrowser2ProtocolGuid,EFI_NATIVE_INTERFACE,&mPrivateData.FormBrowser2);ASSERT_EFI_ERROR (Status);Status = gBS->InstallProtocolInterface (&mPrivateData.Handle,&gEdkiiFormBrowserEx2ProtocolGuid,EFI_NATIVE_INTERFACE,&mPrivateData.FormBrowserEx2);ASSERT_EFI_ERROR (Status);Status = gBS->InstallProtocolInterface (&mPrivateData.Handle,&gEdkiiFormBrowserExProtocolGuid,EFI_NATIVE_INTERFACE,&mPrivateData.FormBrowserEx);ASSERT_EFI_ERROR (Status);
然后初始化SETUP_DRIVER_PRIVATE_DATA(对应变量mPrivateData):
InitializeListHead (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);InitializeListHead (&mPrivateData.FormBrowserEx2.OverrideQestListHead);
还有初始化EDKII_FORM_DISPLAY_ENGINE_PROTOCOL(对应mFormDisplay,这个Protocol实际上会在DisplayEngineDxe.inf整个模块中安装,所以利用了Callback方式):
Status = gBS->LocateProtocol (&gEdkiiFormDisplayEngineProtocolGuid,NULL,(VOID **) &mFormDisplay);if (EFI_ERROR (Status)) {EfiCreateProtocolNotifyEvent (&gEdkiiFormDisplayEngineProtocolGuid,TPL_CALLBACK,FormDisplayCallback,NULL,&Registration);}
以及FORM_DISPLAY_ENGINE_FORM(对应gDisplayFormData):
/**Initialize the Display form structure data.
**/
VOID
InitializeDisplayFormData (VOID)
{EFI_STATUS Status;gDisplayFormData.Signature = FORM_DISPLAY_ENGINE_FORM_SIGNATURE;gDisplayFormData.Version = FORM_DISPLAY_ENGINE_VERSION_1;gDisplayFormData.ImageId = 0;gDisplayFormData.AnimationId = 0;InitializeListHead (&gDisplayFormData.StatementListHead);InitializeListHead (&gDisplayFormData.StatementListOSF);InitializeListHead (&gDisplayFormData.HotKeyListHead);Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK,EfiEventEmptyFunction,NULL,&mValueChangedEvent);ASSERT_EFI_ERROR (Status);
}
DisplayEngineDxe.inf
首先是安装一个Strings:
gHiiHandle = HiiAddPackages (&gDisplayEngineGuid,ImageHandle,DisplayEngineStrings,NULL);ASSERT (gHiiHandle != NULL);
然后是安装Protocol:
//// Install Form Display protocol//Status = gBS->InstallProtocolInterface (&mPrivateData.Handle,&gEdkiiFormDisplayEngineProtocolGuid,EFI_NATIVE_INTERFACE,&mPrivateData.FromDisplayProt);ASSERT_EFI_ERROR (Status);
之后初始化一堆字符串:
InitializeDisplayStrings();/**Initialize the HII String Token to the correct values.
**/
VOID
InitializeDisplayStrings (VOID)
{gReconnectConfirmChanges = GetToken (STRING_TOKEN (RECONNECT_CONFIRM_CHANGES), gHiiHandle);mUnknownString = GetToken (STRING_TOKEN (UNKNOWN_STRING), gHiiHandle);gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);gNoSubmitIfFailed = GetToken (STRING_TOKEN (NO_SUBMIT_IF_CHECK_FAILED), gHiiHandle);gReconnectFail = GetToken (STRING_TOKEN (RECONNECT_FAILED), gHiiHandle);gReconnectRequired = GetToken (STRING_TOKEN (RECONNECT_REQUIRED), gHiiHandle);gChangesOpt = GetToken (STRING_TOKEN (RECONNECT_CHANGES_OPTIONS), gHiiHandle);gSaveProcess = GetToken (STRING_TOKEN (DISCARD_OR_JUMP), gHiiHandle);gSaveNoSubmitProcess = GetToken (STRING_TOKEN (DISCARD_OR_CHECK), gHiiHandle);gDiscardChange = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_DISCARD), gHiiHandle);gJumpToFormSet = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_JUMP), gHiiHandle);gCheckError = GetToken (STRING_TOKEN (DISCARD_OR_CHECK_CHECK), gHiiHandle);gPromptForData = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);gPromptForPassword = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);gConfirmPassword = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);gConfirmError = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);gPassowordInvalid = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);gPressEnter = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);gEmptyString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);gMiniString = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);gOptionMismatch = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);gFormSuppress = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);gProtocolNotFound = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);gFormNotFound = GetToken (STRING_TOKEN (STATUS_BROWSER_FORM_NOT_FOUND), gHiiHandle);gNoSubmitIf = GetToken (STRING_TOKEN (STATUS_BROWSER_NO_SUBMIT_IF), gHiiHandle);gBrowserError = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle);gConfirmDefaultMsg = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE), gHiiHandle);gConfirmDiscardMsg = GetToken (STRING_TOKEN (CONFIRM_DISCARD_MESSAGE), gHiiHandle);gConfirmSubmitMsg = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE), gHiiHandle);gConfirmResetMsg = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE), gHiiHandle);gConfirmExitMsg = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE), gHiiHandle);gConfirmDefaultMsg2nd = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE_2ND), gHiiHandle);gConfirmSubmitMsg2nd = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE_2ND), gHiiHandle);gConfirmResetMsg2nd = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE_2ND), gHiiHandle);gConfirmExitMsg2nd = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE_2ND), gHiiHandle);gConfirmOpt = GetToken (STRING_TOKEN (CONFIRM_OPTION), gHiiHandle);gConfirmOptYes = GetToken (STRING_TOKEN (CONFIRM_OPTION_YES), gHiiHandle);gConfirmOptNo = GetToken (STRING_TOKEN (CONFIRM_OPTION_NO), gHiiHandle);gConfirmMsgConnect = GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT), gHiiHandle);gConfirmMsgEnd = GetToken (STRING_TOKEN (CONFIRM_OPTION_END), gHiiHandle);gPasswordUnsupported = GetToken (STRING_TOKEN (PASSWORD_NOT_SUPPORTED ), gHiiHandle);
}
之后初始化几个变量:
ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo));ZeroMem (&gOldFormEntry, sizeof (gOldFormEntry));
最后注册几个快捷键:
//// Use BrowserEx2 protocol to register HotKey.// Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2);if (!EFI_ERROR (Status)) {//// Register the default HotKey F9 and F10 again.//HotKey.UnicodeChar = CHAR_NULL;HotKey.ScanCode = SCAN_F10;NewString = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_TEN_STRING), NULL);ASSERT (NewString != NULL);FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);HotKey.ScanCode = SCAN_F9;NewString = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_NINE_STRING), NULL);ASSERT (NewString != NULL);FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
