Jingjingjng0504 2021-11-24 11:17
浏览 184
已结题

UEFI(BIOS)SETUP页面编写因oneof导致页面卡死问题

问题遇到的现象和发生背景

最近学习UEFI Setup页面的页面编写,但是在Vfr窗体文件中加入 oneof 结构的时候进到setup下选择对应的选项就会导致整个setup卡死

问题相关代码,请勿粘贴截图

下面是String.Uni文件:

/=#

#langdef    en-US "English"
#langdef    fr-FR "Français"

#string STR_GUI_TEST_BANNER         #language en-US "Gui Test"
                                    #language fr-FR "Test de l’IG"
#string STR_GUI_TEST_HELP           #language en-US "This selection will take you to the Gui Test"
                                    #language fr-FR "Cette sélection vous conduira au Test Gui"
#string STR_TEST_OPTION_BANNER      #language en-US "Gui Test Menu"
                                    #language fr-FR "Menu de tests d’interface graphique"
#string STR_TEST_FOOTER             #language en-US "This is help information in footer"
                                    #language fr-FR "Ceci est help information in footer"
#string STR_TEST_EMPTY              #language en-US " "
                                    #language fr-FR " "
#string STR_TEST_LIST_TITLE         #language en-US "Gui Test List"
                                    #language fr-FR "Liste des tests d’interface graphique"
#string EXIT                        #language en-US "Press ESC to Exit"
                                    #language fr-FR "Presse le ces de sortir"
#string STR_TEXT_ONE                #language en-US "Text One"
#string STR_TEXT_HELP               #language en-US "Text One Help"
#string STR_TEST_ONE_OF_PROMPT           #language en-US "Test one-of Prompt"
#string STR_TEST_ONE_OF_HELP             #language en-US "oneof help"
#string STR_ONE_OF_TEXT1            #language en-US "one-of Text #1"
#string STR_ONE_OF_TEXT2            #language en-US "one-of Text #2"
#string STR_ONE_OF_TEXT3            #language en-US "one-of Text #3"

#string STR_ENTER_PAGE2             #language en-US "Enter Page2"
#string STR_ENTER_PAGE_HELP         #language en-US "Enter Page Help"

#string STR_ONE_OF_TITLE            #language en-US "One Of"

下面是Vfr文件

#define FORMSET_GUID  { 0x857bc3fe, 0xb974, 0x446d, 0x94, 0x49, 0x5a, 0xd5, 0x41, 0x2e, 0x99, 0x3b }

// #define MY_GUITEST_FORM_ID      0x1000
#define MY_GUITEST_LIST_ID      0x1001

#define LABEL_GUITEST_OPTION        0x00
#define LABEL_ONEOF          0x01
#define LABEL_END                   0xff

typedef struct {
    UINT32 variableId;
} GUI_TEST_VAR_STRUCT;

formset
    guid        = FORMSET_GUID,
    title       = STRING_TOKEN(STR_GUI_TEST_BANNER),    // Gui Test(Front Page)
    help        = STRING_TOKEN(STR_GUI_TEST_HELP),      // Help Info(Fromt Page)
    classguid   = gEfiIfrFrontPageGuid,

    // Define a Buffer Storage, efivarstore is to define a EFI variable storage
    varstore GUI_TEST_VAR_STRUCT,
        // attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
        varid = 0x01,
        name = myVarid,
        guid = FORMSET_GUID;

    form formid     = 1,
            title   = STRING_TOKEN(STR_GUI_TEST_BANNER);    // Gui Test (Option Title)

        subtitle text   = STRING_TOKEN(STR_TEST_EMPTY);
        subtitle text   = STRING_TOKEN(STR_TEST_OPTION_BANNER); // Gui Test Menu(Option Menu)
        subtitle text   = STRING_TOKEN(STR_TEST_EMPTY);

        // label LABEL_GUITEST_OPTION;
        // label LABEL_END;
        text
            help    = STRING_TOKEN(STR_TEXT_ONE),
            text    = STRING_TOKEN(STR_TEXT_HELP);
        
        goto 2,
            prompt  = STRING_TOKEN(STR_TEST_ONE_OF_PROMPT),
            help    = STRING_TOKEN(STR_TEST_ONE_OF_HELP);
        goto 2,
            prompt  = STRING_TOKEN(STR_TEST_ONE_OF_PROMPT),
            help    = STRING_TOKEN(STR_TEST_ONE_OF_HELP);
        goto 2,
            prompt  = STRING_TOKEN(STR_TEST_ONE_OF_PROMPT),
            help    = STRING_TOKEN(STR_TEST_ONE_OF_HELP);

        label LABEL_ONEOF;

        label LABEL_END;
        oneof name = MyTestOneof,
            varid   = myVarid.variableId,
            prompt  = STRING_TOKEN(STR_TEST_ONE_OF_PROMPT),
            help    = STRING_TOKEN(STR_TEST_ONE_OF_HELP),
            flags   = RESET_REQUIRED,

            option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value= 0x0, flags = 0;
            option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value= 0x1, flags = 0;
            option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value= 0x2, flags = DEFAULT;
        endoneof;

        subtitle text   = STRING_TOKEN(STR_TEST_EMPTY);
        subtitle text   = STRING_TOKEN(STR_TEST_FOOTER);    // help Info(Option footer)

    endform;

    form formid     = 2,
        title   = STRING_TOKEN(STR_ONE_OF_TITLE);
        
    endform;

endformset;

下面是模块.h文件

#ifndef _EFI_BOOT_MANAGER_H_
#define _EFI_BOOT_MANAGER_H_

#include <Base.h>
#include <Guid/MdeModuleHii.h>
#include <Guid/GlobalVariable.h>

#include <Protocol/HiiConfigAccess.h>
#include <Protocol/DevicePathToText.h>
#include <Protocol/FormBrowserEx2.h>

#include <Library/PrintLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/HiiLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootManagerLib.h>
//
// These are defined as the same with vfr file
//
#define GUI_TEST_FORMSET_GUID \
  { \
  0x857bc3fe, 0xb974, 0x446d, {0x94, 0x49, 0x5a, 0xd5, 0x41, 0x2e, 0x99, 0x3b} \
  }

#define GUI_TEST_FORM_ID     0x1000

#define LABEL_GUITEST_OPTION        0x00
#define LABEL_GUITEST_OPTION_END    0x01

extern UINT8 MyGuiTestVfrBin[];

#define GUI_TEST_CALLBACK_DATA_SIGNATURE  SIGNATURE_32 ('G', 'T', 'C', 'B')

typedef struct {
  VENDOR_DEVICE_PATH             VendorDevicePath;
  EFI_DEVICE_PATH_PROTOCOL       End;
} HII_VENDOR_DEVICE_PATH;

typedef struct {
  UINTN                           Signature;

  //
  // HII relative handles
  //
  EFI_HII_HANDLE                  HiiHandle;
  EFI_HANDLE                      DriverHandle;

  //
  // Produced protocols
  //
  EFI_HII_CONFIG_ACCESS_PROTOCOL   ConfigAccess;
} GUI_TEST_CALLBACK_DATA;

/**
 * Customize oneof option in test
 **/
VOID
UiCreateOneofMenu (
  IN EFI_HII_HANDLE  HiiHandle,
  IN VOID            *StartOpCodeHandle
  );

#endif

下面是模块.C文件

/** @file
  The gui test reference implementation

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
#include "MyGuiTest.h"

GUI_TEST_CALLBACK_DATA  gMyGuiTestPrivate = {
  GUI_TEST_CALLBACK_DATA_SIGNATURE,
  NULL,
  NULL,
  {
    // BootManagerExtractConfig,
    // BootManagerRouteConfig,
    // BootManagerCallback
  }
};

HII_VENDOR_DEVICE_PATH mGuiTestHiiVendorDevicePath = {
    {
        {
            HARDWARE_DEVICE_PATH,
            HW_VENDOR_DP,
            {
                (UINT8) (sizeof(VENDOR_DEVICE_PATH)),
                (UINT8) ((sizeof(VENDOR_DEVICE_PATH)) >> 8)
            }
        },
        { 0x1eddbe15, 0x481d, 0x4d2b, { 0x82, 0x77, 0xb1, 0x91, 0xea, 0xf6, 0x65, 0x25 } }
    },
    {
        END_DEVICE_PATH_TYPE,
        END_ENTIRE_DEVICE_PATH_SUBTYPE,
        {
            (UINT8) (END_DEVICE_PATH_LENGTH),
            (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
        }
    }
};

EFI_GUID mGuiTestGuid = GUI_TEST_FORMSET_GUID;
#define ONEOF_QUESTION_ID 0x1006
#define LABEL_ONEOF 0X01
EFI_STATUS
EFIAPI
MyGuiTestUiLibConstructor (
  IN EFI_HANDLE                            ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )
{
  EFI_STATUS                     Status;
  // oneof
  EFI_IFR_GUID_LABEL          *StartGuidLabel;
  VOID                        *StartOpCodeHandle;

  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  // oneof
  StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartGuidLabel->Number       = LABEL_ONEOF;

  //
  // Install Device Path Protocol and Config Access protocol to driver handle
  //
  gMyGuiTestPrivate.DriverHandle = NULL;
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &gMyGuiTestPrivate.DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mGuiTestHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &gMyGuiTestPrivate.ConfigAccess,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Publish our HII data
  //
  gMyGuiTestPrivate.HiiHandle = HiiAddPackages (
                                    &mGuiTestGuid,
                                    gMyGuiTestPrivate.DriverHandle,
                                    MyGuiTestVfrBin,
                                    MyGuiTestUiLibStrings,
                                    NULL
                                    );
  ASSERT (gMyGuiTestPrivate.HiiHandle != NULL);

  // BmInitialBootModeInfo ();
  UiCreateOneofMenu(gMyGuiTestPrivate.HiiHandle, StartOpCodeHandle);

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
MyGuiTestUiLibDestructor (
  IN EFI_HANDLE                            ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )
{
  EFI_STATUS    Status;

  Status = gBS->UninstallMultipleProtocolInterfaces (
                  gMyGuiTestPrivate.DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mGuiTestHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &gMyGuiTestPrivate.ConfigAccess,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  HiiRemovePackages (gMyGuiTestPrivate.HiiHandle);

  return EFI_SUCCESS;
}

VOID
UiCreateOneofMenu (
  IN EFI_HII_HANDLE  HiiHandle,
  IN VOID            *StartOpCodeHandle
  )
{
  VOID                        *OptionsOpCodeHandle;

  // 1. allocate memory for Handle
  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT(OptionsOpCodeHandle != NULL);

  // 2. Create oneof options opcpde
  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN(STR_ONE_OF_TEXT1),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    2
  );
  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN(STR_ONE_OF_TEXT2),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    1
  );
  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN(STR_ONE_OF_TEXT3),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    3
  );

  // 3. Create oneof opcode
  HiiCreateOneOfOpCode (
    StartOpCodeHandle,
    ONEOF_QUESTION_ID,
    0,
    0,
    STRING_TOKEN (STR_TEST_ONE_OF_PROMPT),
    STRING_TOKEN (STR_TEST_ONE_OF_HELP),
    0, // EFI_IFR_FLAG_CALLBACK,
    EFI_IFR_NUMERIC_SIZE_4,
    OptionsOpCodeHandle,
    NULL
    );
}

下面是模块.inf文件

[defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = MyGuiTestUiLib
  MODULE_UNI_FILE                = MyGuiTestUiLib.uni
  FILE_GUID                      = CCB2DCE1-4FC8-41CB-88C5-D349E134C9FD
  MODULE_TYPE                    = DXE_DRIVER
  VERSION_STRING                 = 1.0
  LIBRARY_CLASS                  = NULL|DXE_DRIVER UEFI_APPLICATION
  CONSTRUCTOR                    = MyGuiTestUiLibConstructor
  DESTRUCTOR                     = MyGuiTestUiLibDestructor

[Sources]
  MyGuiTest.h
  MyGuiTestVfr.Vfr
  MyGuiTestStrings.uni
  MyGuiTest.c

[Packages]
  MdePkg/MdePkg.dec
  MdeModulePkg/MdeModulePkg.dec

[LibraryClasses]
  UefiRuntimeServicesTableLib
  ReportStatusCodeLib
  MemoryAllocationLib
  UefiLib
  UefiBootServicesTableLib
  BaseMemoryLib
  DebugLib
  PrintLib
  HiiLib
  UefiBootManagerLib

[Guids]
  gEfiIfrTianoGuid                             
  gEfiIfrFrontPageGuid                         

[Protocols]
  gEfiHiiConfigAccessProtocolGuid            
  gEfiDevicePathToTextProtocolGuid         
  gEdkiiFormBrowserEx2ProtocolGuid      

[FeaturePcd]

[Pcd]
  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow                   
  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn                    
  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution       
  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution         
  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn                
  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow                    
  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution   
  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution     

运行结果及报错内容

原本不加上面的oneof那一组的时候,该选项是可以直接进去并显示前面的text的,但是加了oneof之后,选择Gui Test选项回车,直接就卡死完全没反映了

img

每次卡死之后看到的日志信息如下:

img

我的解答思路和尝试过的方法

不知道是不是因为逻辑处理的问题,但是问过一些人,他们说这个完全就是界面编写的问题,只涉及到.Vfr文件,跟.c中的逻辑流程没什么太大的关系,我也尝试了去写oneof Opcode的逻辑处理,但是没有奇效。而且反复检查了上述代码没发现哪里有问题

我想要达到的结果

请大家帮忙看看,卡在这里好几天了,为什么会直接卡死

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 12月2日
    • 修改了问题 11月24日
    • 修改了问题 11月24日
    • 创建了问题 11月24日

    悬赏问题

    • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
    • ¥50 我撰写的python爬虫爬不了 要爬的网址有反爬机制
    • ¥15 Centos / PETSc / PETGEM
    • ¥15 centos7.9 IPv6端口telnet和端口监控问题
    • ¥120 计算机网络的新校区组网设计
    • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
    • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
    • ¥20 海浪数据 南海地区海况数据,波浪数据
    • ¥20 软件测试决策法疑问求解答
    • ¥15 win11 23H2删除推荐的项目,支持注册表等