【UEFI实战】HII之涉及模块

模块

HII的交互逻辑如下图所示:

在这里插入图片描述

其中上边是输入设备,比如键盘、鼠标等;右边是输出设备,比如显示器;左边是UEFI变量,用来存放HII会涉及到的数据。这三个部分都属于UEFI基础,不是这里介绍的对象,这里主要说明中间紫色部分的IFR BrowserHII 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);}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部