BIOS/UEFI基础——UEFI用户交互界面使用说明之基础驱动

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jiangwei0512/article/details/81913267

基础驱动综述

UEFI用户交互界面的框架如下所示:

其中上边是输入设备,比如键盘、鼠标等;右边是输出设备,比如显示器;左边是UEFI变量,用来存放交互界面会涉及到的变量。这三个部分都属于UEFI基础,不属于这里介绍的对象。

剩余的部分就是用户交互界面的基本模块,对应到代码中有如下的几个:

  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf

除此之外,其它的模块(就是上图绿色部分Driver)也会提供用户交互界面需要的元素,这通常是为了完成该模块需要的操作。

在上面的三个模块中,HiiDatabaseDxe.inf这个模块用来初始化并安装操作界面元素的Protocol以及配置相关的Protocol,这些界面元素包括Fonts,Strings,Forms、Images等,就是上图中下边部分的内容。SetupBrowserDxe.inf这个模块依赖于HiiDatabaseDxe.inf,它提供了上图中间部分的实现,实际上是整个用户交互界面的引擎,用来实现各类必要的操作(实际上也不是它来实现,它只是调用了在绿色部分Driver中的操作)。DisplayEngineDxe.inf是配合SetupBrowserDxe.inf一起使用的,它依赖于SetupBrowserDxe.inf。

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,后续会介绍。

SetupBrowserDxe.inf

该模块依赖于在HiiDatabaseDxe.inf中安装的某些Protocol:

  //
  // 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整个模块中安装):

  Status = gBS->LocateProtocol (
                  &gEdkiiFormDisplayEngineProtocolGuid,
                  NULL,
                  (VOID **) &mFormDisplay
                  );

  if (EFI_ERROR (Status)) {
    EfiCreateProtocolNotifyEvent (
      &gEdkiiFormDisplayEngineProtocolGuid,
      TPL_CALLBACK,
      FormDisplayCallback,
      NULL,
      &Registration
      );
  }

以及FORM_DISPLAY_ENGINE_FORM(对应gDisplayFormData):

InitializeDisplayFormData ();

/**

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

猜你喜欢

转载自blog.csdn.net/jiangwei0512/article/details/81913267