写在前面

UEFI有自己的用户交互界面,它的实现基础被称为HII(Human Interface Infrastructure),本文是一系列介绍HII实现的第一篇。这里从开源EDK代码中的界面(称为Front Page)入手,介绍它的实现,并进一步说明整个HII。

之前已经写过一系列跟Setup相关的文档,内容有重复及补充。

入口说明

Front Page的实现代码可以在https://gitee.com/jiangwei0512/edk2-beni)找到,编译执行之后的结果大致如下:

它对应的是一个启动项程序UiApp,模块代码是MdeModulePkg\Application\UiApp\UiApp.inf,该模块的入口函数是InitializeUserInterface()(位于MdeModulePkg\Application\UiApp\FrontPage.c)。

初始化的大致流程如下:

#mermaid-svg-ijEeSlHFowWpm12y .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-ijEeSlHFowWpm12y .label text{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y .node rect,#mermaid-svg-ijEeSlHFowWpm12y .node circle,#mermaid-svg-ijEeSlHFowWpm12y .node ellipse,#mermaid-svg-ijEeSlHFowWpm12y .node polygon,#mermaid-svg-ijEeSlHFowWpm12y .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-ijEeSlHFowWpm12y .node .label{text-align:center;fill:#333}#mermaid-svg-ijEeSlHFowWpm12y .node.clickable{cursor:pointer}#mermaid-svg-ijEeSlHFowWpm12y .arrowheadPath{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-ijEeSlHFowWpm12y .flowchart-link{stroke:#333;fill:none}#mermaid-svg-ijEeSlHFowWpm12y .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-ijEeSlHFowWpm12y .edgeLabel rect{opacity:0.9}#mermaid-svg-ijEeSlHFowWpm12y .edgeLabel span{color:#333}#mermaid-svg-ijEeSlHFowWpm12y .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-ijEeSlHFowWpm12y .cluster text{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-ijEeSlHFowWpm12y .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-ijEeSlHFowWpm12y text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-ijEeSlHFowWpm12y .actor-line{stroke:grey}#mermaid-svg-ijEeSlHFowWpm12y .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-ijEeSlHFowWpm12y .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-ijEeSlHFowWpm12y #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-ijEeSlHFowWpm12y .sequenceNumber{fill:#fff}#mermaid-svg-ijEeSlHFowWpm12y #sequencenumber{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y #crosshead path{fill:#333;stroke:#333}#mermaid-svg-ijEeSlHFowWpm12y .messageText{fill:#333;stroke:#333}#mermaid-svg-ijEeSlHFowWpm12y .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-ijEeSlHFowWpm12y .labelText,#mermaid-svg-ijEeSlHFowWpm12y .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-ijEeSlHFowWpm12y .loopText,#mermaid-svg-ijEeSlHFowWpm12y .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-ijEeSlHFowWpm12y .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-ijEeSlHFowWpm12y .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-ijEeSlHFowWpm12y .noteText,#mermaid-svg-ijEeSlHFowWpm12y .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-ijEeSlHFowWpm12y .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-ijEeSlHFowWpm12y .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-ijEeSlHFowWpm12y .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-ijEeSlHFowWpm12y .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y .section{stroke:none;opacity:0.2}#mermaid-svg-ijEeSlHFowWpm12y .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-ijEeSlHFowWpm12y .section2{fill:#fff400}#mermaid-svg-ijEeSlHFowWpm12y .section1,#mermaid-svg-ijEeSlHFowWpm12y .section3{fill:#fff;opacity:0.2}#mermaid-svg-ijEeSlHFowWpm12y .sectionTitle0{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y .sectionTitle1{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y .sectionTitle2{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y .sectionTitle3{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-ijEeSlHFowWpm12y .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y .grid path{stroke-width:0}#mermaid-svg-ijEeSlHFowWpm12y .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-ijEeSlHFowWpm12y .task{stroke-width:2}#mermaid-svg-ijEeSlHFowWpm12y .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y .taskText:not([font-size]){font-size:11px}#mermaid-svg-ijEeSlHFowWpm12y .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-ijEeSlHFowWpm12y .task.clickable{cursor:pointer}#mermaid-svg-ijEeSlHFowWpm12y .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-ijEeSlHFowWpm12y .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-ijEeSlHFowWpm12y .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-ijEeSlHFowWpm12y .taskText0,#mermaid-svg-ijEeSlHFowWpm12y .taskText1,#mermaid-svg-ijEeSlHFowWpm12y .taskText2,#mermaid-svg-ijEeSlHFowWpm12y .taskText3{fill:#fff}#mermaid-svg-ijEeSlHFowWpm12y .task0,#mermaid-svg-ijEeSlHFowWpm12y .task1,#mermaid-svg-ijEeSlHFowWpm12y .task2,#mermaid-svg-ijEeSlHFowWpm12y .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-ijEeSlHFowWpm12y .taskTextOutside0,#mermaid-svg-ijEeSlHFowWpm12y .taskTextOutside2{fill:#000}#mermaid-svg-ijEeSlHFowWpm12y .taskTextOutside1,#mermaid-svg-ijEeSlHFowWpm12y .taskTextOutside3{fill:#000}#mermaid-svg-ijEeSlHFowWpm12y .active0,#mermaid-svg-ijEeSlHFowWpm12y .active1,#mermaid-svg-ijEeSlHFowWpm12y .active2,#mermaid-svg-ijEeSlHFowWpm12y .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-ijEeSlHFowWpm12y .activeText0,#mermaid-svg-ijEeSlHFowWpm12y .activeText1,#mermaid-svg-ijEeSlHFowWpm12y .activeText2,#mermaid-svg-ijEeSlHFowWpm12y .activeText3{fill:#000 !important}#mermaid-svg-ijEeSlHFowWpm12y .done0,#mermaid-svg-ijEeSlHFowWpm12y .done1,#mermaid-svg-ijEeSlHFowWpm12y .done2,#mermaid-svg-ijEeSlHFowWpm12y .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-ijEeSlHFowWpm12y .doneText0,#mermaid-svg-ijEeSlHFowWpm12y .doneText1,#mermaid-svg-ijEeSlHFowWpm12y .doneText2,#mermaid-svg-ijEeSlHFowWpm12y .doneText3{fill:#000 !important}#mermaid-svg-ijEeSlHFowWpm12y .crit0,#mermaid-svg-ijEeSlHFowWpm12y .crit1,#mermaid-svg-ijEeSlHFowWpm12y .crit2,#mermaid-svg-ijEeSlHFowWpm12y .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-ijEeSlHFowWpm12y .activeCrit0,#mermaid-svg-ijEeSlHFowWpm12y .activeCrit1,#mermaid-svg-ijEeSlHFowWpm12y .activeCrit2,#mermaid-svg-ijEeSlHFowWpm12y .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-ijEeSlHFowWpm12y .doneCrit0,#mermaid-svg-ijEeSlHFowWpm12y .doneCrit1,#mermaid-svg-ijEeSlHFowWpm12y .doneCrit2,#mermaid-svg-ijEeSlHFowWpm12y .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-ijEeSlHFowWpm12y .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-ijEeSlHFowWpm12y .milestoneText{font-style:italic}#mermaid-svg-ijEeSlHFowWpm12y .doneCritText0,#mermaid-svg-ijEeSlHFowWpm12y .doneCritText1,#mermaid-svg-ijEeSlHFowWpm12y .doneCritText2,#mermaid-svg-ijEeSlHFowWpm12y .doneCritText3{fill:#000 !important}#mermaid-svg-ijEeSlHFowWpm12y .activeCritText0,#mermaid-svg-ijEeSlHFowWpm12y .activeCritText1,#mermaid-svg-ijEeSlHFowWpm12y .activeCritText2,#mermaid-svg-ijEeSlHFowWpm12y .activeCritText3{fill:#000 !important}#mermaid-svg-ijEeSlHFowWpm12y .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-ijEeSlHFowWpm12y g.classGroup text .title{font-weight:bolder}#mermaid-svg-ijEeSlHFowWpm12y g.clickable{cursor:pointer}#mermaid-svg-ijEeSlHFowWpm12y g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-ijEeSlHFowWpm12y g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-ijEeSlHFowWpm12y .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-ijEeSlHFowWpm12y .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-ijEeSlHFowWpm12y .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-ijEeSlHFowWpm12y .dashed-line{stroke-dasharray:3}#mermaid-svg-ijEeSlHFowWpm12y #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ijEeSlHFowWpm12y #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ijEeSlHFowWpm12y #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-ijEeSlHFowWpm12y #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-ijEeSlHFowWpm12y #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ijEeSlHFowWpm12y #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ijEeSlHFowWpm12y #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ijEeSlHFowWpm12y #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ijEeSlHFowWpm12y .commit-id,#mermaid-svg-ijEeSlHFowWpm12y .commit-msg,#mermaid-svg-ijEeSlHFowWpm12y .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-ijEeSlHFowWpm12y g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-ijEeSlHFowWpm12y g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-ijEeSlHFowWpm12y g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-ijEeSlHFowWpm12y .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-ijEeSlHFowWpm12y .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-ijEeSlHFowWpm12y .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-ijEeSlHFowWpm12y .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-ijEeSlHFowWpm12y .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-ijEeSlHFowWpm12y .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-ijEeSlHFowWpm12y .edgeLabel text{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-ijEeSlHFowWpm12y .node circle.state-start{fill:black;stroke:black}#mermaid-svg-ijEeSlHFowWpm12y .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-ijEeSlHFowWpm12y #statediagram-barbEnd{fill:#9370db}#mermaid-svg-ijEeSlHFowWpm12y .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-ijEeSlHFowWpm12y .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-ijEeSlHFowWpm12y .statediagram-state .divider{stroke:#9370db}#mermaid-svg-ijEeSlHFowWpm12y .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-ijEeSlHFowWpm12y .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-ijEeSlHFowWpm12y .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-ijEeSlHFowWpm12y .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-ijEeSlHFowWpm12y .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-ijEeSlHFowWpm12y .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-ijEeSlHFowWpm12y .note-edge{stroke-dasharray:5}#mermaid-svg-ijEeSlHFowWpm12y .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-ijEeSlHFowWpm12y .error-icon{fill:#522}#mermaid-svg-ijEeSlHFowWpm12y .error-text{fill:#522;stroke:#522}#mermaid-svg-ijEeSlHFowWpm12y .edge-thickness-normal{stroke-width:2px}#mermaid-svg-ijEeSlHFowWpm12y .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-ijEeSlHFowWpm12y .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-ijEeSlHFowWpm12y .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-ijEeSlHFowWpm12y .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-ijEeSlHFowWpm12y .marker{fill:#333}#mermaid-svg-ijEeSlHFowWpm12y .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-ijEeSlHFowWpm12y {color: rgba(0, 0, 0, 0.75);font: ;}

进入UI
退出UI之后的清理
初始化图形模式参数
关闭软件看门狗
清屏
安装字体
初始化HII字符串
设置终端模式,参数就来自第一步
进入UI入口
UI入口
退出Front Page之后的清理
UI入口
如果有必要就初始化启动设备
刷新启动项
Logo操作
初始化Front Page
显示Front Page

上述流程中最主要的是两个部分,”初始化Front Page“和”显示Front Page“,对应到两个函数InitializeFrontPage()CallFrontPage(),它们可以连起来看,主要做的事情就是两个:一个是准备素材,这里的素材指的是uni文件、vfr文件等表示的HII数据;另一个是显示这些素材,它通过一个EFI_FORM_BROWSER2_PROTOCOL来完成,这个Protocol提供两个接口,SendForm()用来显示配置好的HII,BrowserCallback()会被回调函数调用,用来获取和设置界面元素。

界面元素

在HII中构成一个界面的元素大致有四种,分别是字符串(Strings)、结构(Forms)、字体(Fonts)和图像(Images),如下图所示(最右边的Questions等是结构的组成部分,这里可以暂时不管,后续会介绍):

字符串通过uni文件产生,结构通过vfr文件产生,字体暂不介绍,而图像则没有特别好介绍的。本例的Front Page中使用了结构、字符串和字体,图像则没有使用到。

元素更新

元素更新主要发生在InitializeFrontPage()函数中,对应的代码:

  ////Updata Front Page banner strings//UpdateFrontPageBannerStrings ();//// Update front page menus.//UpdateFrontPageForm();
  • 前者UpdateFrontPageBannerStrings()主要是获取标记①(Token)对应的字符串的值并设置到对应的标记②中,它初始化Front Page的上半区静态部分:

以代码为例的话就像下面的那样:

    NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NULL);UiCustomizeFrontPageBanner (1, TRUE, &NewString);HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NewString, NULL);FreePool (NewString);

这里的标记STR_FRONT_PAGE_COMPUTER_MODEL出现了两次,虽然名字相同,但是是来自不同的文件,分别是uni文件中的:

#string STR_FRONT_PAGE_COMPUTER_MODEL  #language en-US  ""#language fr-FR  ""

和来自vfr文件中的:

    bannertitle = STRING_TOKEN(STR_FRONT_PAGE_COMPUTER_MODEL),line  1,align left;

标记①的操作通过HiiGetString()获取字符串,标记②的操作通过HiiSetString()设置字符串。不过两者本来就需要是一致的,所以也不需要特意去区分。

  • 后者UpdateFrontPageForm()更新其它动态的部分,而动态的部分通过vfr文件查看可以看到它们位于两个操作码之间:
    label LABEL_FRANTPAGE_INFORMATION;//// This is where we will dynamically add a Action type op-code to show// the platform information.//label LABEL_END;

对应的代码:

VOID
UpdateFrontPageForm (VOID)
{VOID                        *StartOpCodeHandle;VOID                        *EndOpCodeHandle;EFI_IFR_GUID_LABEL          *StartGuidLabel;EFI_IFR_GUID_LABEL          *EndGuidLabel;//// Allocate space for creation of UpdateData Buffer//StartOpCodeHandle = HiiAllocateOpCodeHandle ();ASSERT (StartOpCodeHandle != NULL);EndOpCodeHandle = HiiAllocateOpCodeHandle ();ASSERT (EndOpCodeHandle != NULL);//// Create Hii Extend Label OpCode as the start opcode//StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;StartGuidLabel->Number       = LABEL_FRANTPAGE_INFORMATION;  // 对应vfr中的LABEL_FRANTPAGE_INFORMATION//// Create Hii Extend Label OpCode as the end opcode//EndGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;EndGuidLabel->Number       = LABEL_END;   // 对应vfr中的LABEL_END////Updata Front Page form//UiCustomizeFrontPage (gFrontPagePrivate.HiiHandle,StartOpCodeHandle);HiiUpdateForm (gFrontPagePrivate.HiiHandle,&mFrontPageGuid,FRONT_PAGE_FORM_ID,StartOpCodeHandle,EndOpCodeHandle);HiiFreeOpCodeHandle (StartOpCodeHandle);HiiFreeOpCodeHandle (EndOpCodeHandle);
}

这里的两个部分(StartOpCodeHandleEndOpCodeHandle)组合构成了Front Page剩余的部分,其过程如下:

  1. 通过函数HiiAllocateOpCodeHandle()创建两个OpCodeHandle,它们对应的是同一个结构体:
typedef struct {UINT8  *Buffer;UINTN  BufferSize;UINTN  Position;
} HII_LIB_OPCODE_BUFFER;

创建好之后的结构体中Buffer是一个大小为0x200字节的空间;BufferSize就是0x200;Position初始化为0,它相当于存放其它操作码的容器。

  1. 创建两个OpCode,会使用到前面创建的OpCodeHandle:
StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
StartGuidLabel->Number       = LABEL_FRANTPAGE_INFORMATION;

HiiCreateGuidOpCode()的第一个参数就是OpCodeHandle;第二个参数是一个GUID;第三个参数是可选的,可以是NULL;第四个参数是组件元素结构体的大小。本例创建了两个EFI_IFR_GUID_LABEL结构体(跟vfr文件中的label对应),它也是HiiCreateGuidOpCode()的返回值,其结构如下:

///
/// Label opcode.
///
typedef struct _EFI_IFR_GUID_LABEL {EFI_IFR_OP_HEADER   Header;////// EFI_IFR_TIANO_GUID.///EFI_GUID            Guid;////// EFI_IFR_EXTEND_OP_LABEL.///UINT8               ExtendOpCode;////// Label Number.///UINT16              Number;
} EFI_IFR_GUID_LABEL;

后面的两句代码用来初始化EFI_IFR_GUID_LABEL结构体的后两个参数,其中Number就对应到vfr文件中的label名,本例中分别是LABEL_FRANTPAGE_INFORMATIONLABEL_END

  1. OpCode的自定义,其实就是在StartOpCodeHandleEndOpCodeHandle之间创建自定义的元素。
  2. 更新Front Page结构,更新的部分就是前面代码中增加的自定义元素。
  3. 释放资源。

这里最重要的是第3步,对应如下的函数:

VOID
UiCustomizeFrontPage (IN EFI_HII_HANDLE  HiiHandle,IN VOID            *StartOpCodeHandle)
{//// Create "Select Language" menu with Oneof opcode.//UiCreateLanguageMenu (HiiHandle, StartOpCodeHandle);//// Create empty line.//UiCreateEmptyLine(HiiHandle, StartOpCodeHandle);//// Find third party drivers which need to be shown in the front page.//UiListThirdPartyDrivers (HiiHandle, &gEfiIfrFrontPageGuid, NULL, StartOpCodeHandle);//// Create empty line.//UiCreateEmptyLine(HiiHandle, StartOpCodeHandle);//// Create "Continue" menu.//UiCreateContinueMenu(HiiHandle, StartOpCodeHandle);//// Create reset menu.//UiCreateResetMenu(HiiHandle, StartOpCodeHandle);
}

基本上图中显示的部分都有对应的函数,但是底部黑色部分并没有,它们是根据特定情况而产生的,比如<Enter>= Select Entry是因为UiCreateLanguageMenu()而显示的,而↑↓=Move Highlight只要有创建上述的元素就会有显示。动作显示的组件有一个包含的关系,如下图所示:

#mermaid-svg-VMUdpId3CXmzYJ9N .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .label text{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .node rect,#mermaid-svg-VMUdpId3CXmzYJ9N .node circle,#mermaid-svg-VMUdpId3CXmzYJ9N .node ellipse,#mermaid-svg-VMUdpId3CXmzYJ9N .node polygon,#mermaid-svg-VMUdpId3CXmzYJ9N .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-VMUdpId3CXmzYJ9N .node .label{text-align:center;fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .node.clickable{cursor:pointer}#mermaid-svg-VMUdpId3CXmzYJ9N .arrowheadPath{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-VMUdpId3CXmzYJ9N .flowchart-link{stroke:#333;fill:none}#mermaid-svg-VMUdpId3CXmzYJ9N .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-VMUdpId3CXmzYJ9N .edgeLabel rect{opacity:0.9}#mermaid-svg-VMUdpId3CXmzYJ9N .edgeLabel span{color:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-VMUdpId3CXmzYJ9N .cluster text{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-VMUdpId3CXmzYJ9N .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-VMUdpId3CXmzYJ9N text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-VMUdpId3CXmzYJ9N .actor-line{stroke:grey}#mermaid-svg-VMUdpId3CXmzYJ9N .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-VMUdpId3CXmzYJ9N #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .sequenceNumber{fill:#fff}#mermaid-svg-VMUdpId3CXmzYJ9N #sequencenumber{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N #crosshead path{fill:#333;stroke:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .messageText{fill:#333;stroke:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-VMUdpId3CXmzYJ9N .labelText,#mermaid-svg-VMUdpId3CXmzYJ9N .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-VMUdpId3CXmzYJ9N .loopText,#mermaid-svg-VMUdpId3CXmzYJ9N .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-VMUdpId3CXmzYJ9N .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-VMUdpId3CXmzYJ9N .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-VMUdpId3CXmzYJ9N .noteText,#mermaid-svg-VMUdpId3CXmzYJ9N .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-VMUdpId3CXmzYJ9N .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-VMUdpId3CXmzYJ9N .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-VMUdpId3CXmzYJ9N .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-VMUdpId3CXmzYJ9N .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N .section{stroke:none;opacity:0.2}#mermaid-svg-VMUdpId3CXmzYJ9N .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-VMUdpId3CXmzYJ9N .section2{fill:#fff400}#mermaid-svg-VMUdpId3CXmzYJ9N .section1,#mermaid-svg-VMUdpId3CXmzYJ9N .section3{fill:#fff;opacity:0.2}#mermaid-svg-VMUdpId3CXmzYJ9N .sectionTitle0{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .sectionTitle1{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .sectionTitle2{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .sectionTitle3{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-VMUdpId3CXmzYJ9N .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N .grid path{stroke-width:0}#mermaid-svg-VMUdpId3CXmzYJ9N .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-VMUdpId3CXmzYJ9N .task{stroke-width:2}#mermaid-svg-VMUdpId3CXmzYJ9N .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N .taskText:not([font-size]){font-size:11px}#mermaid-svg-VMUdpId3CXmzYJ9N .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-VMUdpId3CXmzYJ9N .task.clickable{cursor:pointer}#mermaid-svg-VMUdpId3CXmzYJ9N .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-VMUdpId3CXmzYJ9N .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-VMUdpId3CXmzYJ9N .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-VMUdpId3CXmzYJ9N .taskText0,#mermaid-svg-VMUdpId3CXmzYJ9N .taskText1,#mermaid-svg-VMUdpId3CXmzYJ9N .taskText2,#mermaid-svg-VMUdpId3CXmzYJ9N .taskText3{fill:#fff}#mermaid-svg-VMUdpId3CXmzYJ9N .task0,#mermaid-svg-VMUdpId3CXmzYJ9N .task1,#mermaid-svg-VMUdpId3CXmzYJ9N .task2,#mermaid-svg-VMUdpId3CXmzYJ9N .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-VMUdpId3CXmzYJ9N .taskTextOutside0,#mermaid-svg-VMUdpId3CXmzYJ9N .taskTextOutside2{fill:#000}#mermaid-svg-VMUdpId3CXmzYJ9N .taskTextOutside1,#mermaid-svg-VMUdpId3CXmzYJ9N .taskTextOutside3{fill:#000}#mermaid-svg-VMUdpId3CXmzYJ9N .active0,#mermaid-svg-VMUdpId3CXmzYJ9N .active1,#mermaid-svg-VMUdpId3CXmzYJ9N .active2,#mermaid-svg-VMUdpId3CXmzYJ9N .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-VMUdpId3CXmzYJ9N .activeText0,#mermaid-svg-VMUdpId3CXmzYJ9N .activeText1,#mermaid-svg-VMUdpId3CXmzYJ9N .activeText2,#mermaid-svg-VMUdpId3CXmzYJ9N .activeText3{fill:#000 !important}#mermaid-svg-VMUdpId3CXmzYJ9N .done0,#mermaid-svg-VMUdpId3CXmzYJ9N .done1,#mermaid-svg-VMUdpId3CXmzYJ9N .done2,#mermaid-svg-VMUdpId3CXmzYJ9N .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-VMUdpId3CXmzYJ9N .doneText0,#mermaid-svg-VMUdpId3CXmzYJ9N .doneText1,#mermaid-svg-VMUdpId3CXmzYJ9N .doneText2,#mermaid-svg-VMUdpId3CXmzYJ9N .doneText3{fill:#000 !important}#mermaid-svg-VMUdpId3CXmzYJ9N .crit0,#mermaid-svg-VMUdpId3CXmzYJ9N .crit1,#mermaid-svg-VMUdpId3CXmzYJ9N .crit2,#mermaid-svg-VMUdpId3CXmzYJ9N .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-VMUdpId3CXmzYJ9N .activeCrit0,#mermaid-svg-VMUdpId3CXmzYJ9N .activeCrit1,#mermaid-svg-VMUdpId3CXmzYJ9N .activeCrit2,#mermaid-svg-VMUdpId3CXmzYJ9N .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-VMUdpId3CXmzYJ9N .doneCrit0,#mermaid-svg-VMUdpId3CXmzYJ9N .doneCrit1,#mermaid-svg-VMUdpId3CXmzYJ9N .doneCrit2,#mermaid-svg-VMUdpId3CXmzYJ9N .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-VMUdpId3CXmzYJ9N .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-VMUdpId3CXmzYJ9N .milestoneText{font-style:italic}#mermaid-svg-VMUdpId3CXmzYJ9N .doneCritText0,#mermaid-svg-VMUdpId3CXmzYJ9N .doneCritText1,#mermaid-svg-VMUdpId3CXmzYJ9N .doneCritText2,#mermaid-svg-VMUdpId3CXmzYJ9N .doneCritText3{fill:#000 !important}#mermaid-svg-VMUdpId3CXmzYJ9N .activeCritText0,#mermaid-svg-VMUdpId3CXmzYJ9N .activeCritText1,#mermaid-svg-VMUdpId3CXmzYJ9N .activeCritText2,#mermaid-svg-VMUdpId3CXmzYJ9N .activeCritText3{fill:#000 !important}#mermaid-svg-VMUdpId3CXmzYJ9N .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-VMUdpId3CXmzYJ9N g.classGroup text .title{font-weight:bolder}#mermaid-svg-VMUdpId3CXmzYJ9N g.clickable{cursor:pointer}#mermaid-svg-VMUdpId3CXmzYJ9N g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-VMUdpId3CXmzYJ9N g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-VMUdpId3CXmzYJ9N .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-VMUdpId3CXmzYJ9N .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-VMUdpId3CXmzYJ9N .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-VMUdpId3CXmzYJ9N .dashed-line{stroke-dasharray:3}#mermaid-svg-VMUdpId3CXmzYJ9N #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-VMUdpId3CXmzYJ9N #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-VMUdpId3CXmzYJ9N #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-VMUdpId3CXmzYJ9N #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-VMUdpId3CXmzYJ9N #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-VMUdpId3CXmzYJ9N #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-VMUdpId3CXmzYJ9N #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-VMUdpId3CXmzYJ9N #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-VMUdpId3CXmzYJ9N .commit-id,#mermaid-svg-VMUdpId3CXmzYJ9N .commit-msg,#mermaid-svg-VMUdpId3CXmzYJ9N .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-VMUdpId3CXmzYJ9N g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-VMUdpId3CXmzYJ9N g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-VMUdpId3CXmzYJ9N g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-VMUdpId3CXmzYJ9N .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-VMUdpId3CXmzYJ9N .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-VMUdpId3CXmzYJ9N .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-VMUdpId3CXmzYJ9N .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-VMUdpId3CXmzYJ9N .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-VMUdpId3CXmzYJ9N .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-VMUdpId3CXmzYJ9N .edgeLabel text{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-VMUdpId3CXmzYJ9N .node circle.state-start{fill:black;stroke:black}#mermaid-svg-VMUdpId3CXmzYJ9N .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-VMUdpId3CXmzYJ9N #statediagram-barbEnd{fill:#9370db}#mermaid-svg-VMUdpId3CXmzYJ9N .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-VMUdpId3CXmzYJ9N .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-VMUdpId3CXmzYJ9N .statediagram-state .divider{stroke:#9370db}#mermaid-svg-VMUdpId3CXmzYJ9N .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-VMUdpId3CXmzYJ9N .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-VMUdpId3CXmzYJ9N .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-VMUdpId3CXmzYJ9N .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-VMUdpId3CXmzYJ9N .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-VMUdpId3CXmzYJ9N .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-VMUdpId3CXmzYJ9N .note-edge{stroke-dasharray:5}#mermaid-svg-VMUdpId3CXmzYJ9N .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-VMUdpId3CXmzYJ9N .error-icon{fill:#522}#mermaid-svg-VMUdpId3CXmzYJ9N .error-text{fill:#522;stroke:#522}#mermaid-svg-VMUdpId3CXmzYJ9N .edge-thickness-normal{stroke-width:2px}#mermaid-svg-VMUdpId3CXmzYJ9N .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-VMUdpId3CXmzYJ9N .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-VMUdpId3CXmzYJ9N .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-VMUdpId3CXmzYJ9N .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-VMUdpId3CXmzYJ9N .marker{fill:#333}#mermaid-svg-VMUdpId3CXmzYJ9N .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-VMUdpId3CXmzYJ9N {color: rgba(0, 0, 0, 0.75);font: ;}

起始标签
单选框
若干单选项
结束标签
空白行
第三方驱动提供的界面
空白行
Continue动作条
Reset动作条

后面的小节介绍如何创建图中的动态显示部分。

创建菜单

UiCreateLanguageMenu()的具体的代码:

VOID
UiCreateLanguageMenu (IN EFI_HII_HANDLE              HiiHandle,IN VOID                        *StartOpCodeHandle)
{CHAR8                       *LangCode;CHAR8                       *Lang;UINTN                       LangSize;CHAR8                       *CurrentLang;UINTN                       OptionCount;CHAR16                      *StringBuffer;VOID                        *OptionsOpCodeHandle;UINTN                       StringSize;EFI_STATUS                  Status;EFI_HII_STRING_PROTOCOL     *HiiString;Lang         = NULL;StringBuffer = NULL;//// Init OpCode Handle and Allocate space for creation of UpdateData Buffer//OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();ASSERT (OptionsOpCodeHandle != NULL);GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL);//// Get Support language list from variable.//GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&gLanguageString, NULL);if (gLanguageString == NULL) {gLanguageString = AllocateCopyPool (AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),(CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes));ASSERT (gLanguageString != NULL);}if (gLanguageToken == NULL) {//// Count the language list number.//LangCode = gLanguageString;Lang = AllocatePool (AsciiStrSize (gLanguageString));ASSERT (Lang != NULL);OptionCount = 0;while (*LangCode != 0) {GetNextLanguage (&LangCode, Lang);OptionCount ++;}//// Allocate extra 1 as the end tag.//gLanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID));ASSERT (gLanguageToken != NULL);Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);ASSERT_EFI_ERROR (Status);LangCode     = gLanguageString;OptionCount  = 0;while (*LangCode != 0) {GetNextLanguage (&LangCode, Lang);StringSize = 0;Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);if (Status == EFI_BUFFER_TOO_SMALL) {StringBuffer = AllocateZeroPool (StringSize);ASSERT (StringBuffer != NULL);Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);ASSERT_EFI_ERROR (Status);}if (EFI_ERROR (Status)) {LangSize = AsciiStrSize (Lang);StringBuffer = AllocatePool (LangSize * sizeof (CHAR16));ASSERT (StringBuffer != NULL);AsciiStrToUnicodeStrS (Lang, StringBuffer, LangSize);}ASSERT (StringBuffer != NULL);gLanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);FreePool (StringBuffer);OptionCount++;}}ASSERT (gLanguageToken != NULL);LangCode = gLanguageString;OptionCount = 0;if (Lang == NULL) {Lang = AllocatePool (AsciiStrSize (gLanguageString));ASSERT (Lang != NULL);}while (*LangCode != 0) {GetNextLanguage (&LangCode, Lang);if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) {HiiCreateOneOfOptionOpCode (OptionsOpCodeHandle,gLanguageToken[OptionCount],EFI_IFR_OPTION_DEFAULT,EFI_IFR_NUMERIC_SIZE_1,(UINT8) OptionCount);gCurrentLanguageIndex = (UINT8) OptionCount;} else {HiiCreateOneOfOptionOpCode (OptionsOpCodeHandle,gLanguageToken[OptionCount],0,EFI_IFR_NUMERIC_SIZE_1,(UINT8) OptionCount);}OptionCount++;}if (CurrentLang != NULL) {FreePool (CurrentLang);}FreePool (Lang);HiiCreateOneOfOpCode (StartOpCodeHandle,FRONT_PAGE_KEY_LANGUAGE,0,0,STRING_TOKEN (STR_LANGUAGE_SELECT),STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),EFI_IFR_FLAG_CALLBACK,EFI_IFR_NUMERIC_SIZE_1,OptionsOpCodeHandle,NULL);
}

这里的大部分代码只是创建选项时需要使用的数据,可以不同特别关注,这里的重要步骤起始只有两个:

  1. 创建一个新的HII_LIB_OPCODE_BUFFER,用来存放单选项,单选项通过HiiCreateOneOfOptionOpCode()函数放到HII_LIB_OPCODE_BUFFER中;
  2. 将存放了单选项的HII_LIB_OPCODE_BUFFER,构建成一个单选框,存放到上一层的HII_LIB_OPCODE_BUFFER中。

创建空行

空行对应到这里的是一个EFI_IFR_SUBTITLE_OP(Subtitle statement),对应的结构体:

typedef struct _EFI_IFR_SUBTITLE {EFI_IFR_OP_HEADER        Header;EFI_IFR_STATEMENT_HEADER Statement;UINT8                    Flags;
} EFI_IFR_SUBTITLE;

但是没有实际的数据,就变成了一个空行,注意创建时的参数都是0:

VOID
UiCreateEmptyLine (IN EFI_HII_HANDLE              HiiHandle,IN VOID                        *StartOpCodeHandle)
{HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NULL_STRING), 0, 0, 0);
}

创建第三方驱动使用的界面

执行流程:

#mermaid-svg-Ui2w7QKeahZql0cW .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-Ui2w7QKeahZql0cW .label text{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW .node rect,#mermaid-svg-Ui2w7QKeahZql0cW .node circle,#mermaid-svg-Ui2w7QKeahZql0cW .node ellipse,#mermaid-svg-Ui2w7QKeahZql0cW .node polygon,#mermaid-svg-Ui2w7QKeahZql0cW .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-Ui2w7QKeahZql0cW .node .label{text-align:center;fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW .node.clickable{cursor:pointer}#mermaid-svg-Ui2w7QKeahZql0cW .arrowheadPath{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-Ui2w7QKeahZql0cW .flowchart-link{stroke:#333;fill:none}#mermaid-svg-Ui2w7QKeahZql0cW .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-Ui2w7QKeahZql0cW .edgeLabel rect{opacity:0.9}#mermaid-svg-Ui2w7QKeahZql0cW .edgeLabel span{color:#333}#mermaid-svg-Ui2w7QKeahZql0cW .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-Ui2w7QKeahZql0cW .cluster text{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-Ui2w7QKeahZql0cW .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-Ui2w7QKeahZql0cW text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-Ui2w7QKeahZql0cW .actor-line{stroke:grey}#mermaid-svg-Ui2w7QKeahZql0cW .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-Ui2w7QKeahZql0cW .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-Ui2w7QKeahZql0cW #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-Ui2w7QKeahZql0cW .sequenceNumber{fill:#fff}#mermaid-svg-Ui2w7QKeahZql0cW #sequencenumber{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW #crosshead path{fill:#333;stroke:#333}#mermaid-svg-Ui2w7QKeahZql0cW .messageText{fill:#333;stroke:#333}#mermaid-svg-Ui2w7QKeahZql0cW .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-Ui2w7QKeahZql0cW .labelText,#mermaid-svg-Ui2w7QKeahZql0cW .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-Ui2w7QKeahZql0cW .loopText,#mermaid-svg-Ui2w7QKeahZql0cW .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-Ui2w7QKeahZql0cW .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-Ui2w7QKeahZql0cW .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-Ui2w7QKeahZql0cW .noteText,#mermaid-svg-Ui2w7QKeahZql0cW .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-Ui2w7QKeahZql0cW .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-Ui2w7QKeahZql0cW .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-Ui2w7QKeahZql0cW .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-Ui2w7QKeahZql0cW .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW .section{stroke:none;opacity:0.2}#mermaid-svg-Ui2w7QKeahZql0cW .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-Ui2w7QKeahZql0cW .section2{fill:#fff400}#mermaid-svg-Ui2w7QKeahZql0cW .section1,#mermaid-svg-Ui2w7QKeahZql0cW .section3{fill:#fff;opacity:0.2}#mermaid-svg-Ui2w7QKeahZql0cW .sectionTitle0{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW .sectionTitle1{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW .sectionTitle2{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW .sectionTitle3{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-Ui2w7QKeahZql0cW .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW .grid path{stroke-width:0}#mermaid-svg-Ui2w7QKeahZql0cW .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-Ui2w7QKeahZql0cW .task{stroke-width:2}#mermaid-svg-Ui2w7QKeahZql0cW .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW .taskText:not([font-size]){font-size:11px}#mermaid-svg-Ui2w7QKeahZql0cW .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-Ui2w7QKeahZql0cW .task.clickable{cursor:pointer}#mermaid-svg-Ui2w7QKeahZql0cW .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Ui2w7QKeahZql0cW .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Ui2w7QKeahZql0cW .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Ui2w7QKeahZql0cW .taskText0,#mermaid-svg-Ui2w7QKeahZql0cW .taskText1,#mermaid-svg-Ui2w7QKeahZql0cW .taskText2,#mermaid-svg-Ui2w7QKeahZql0cW .taskText3{fill:#fff}#mermaid-svg-Ui2w7QKeahZql0cW .task0,#mermaid-svg-Ui2w7QKeahZql0cW .task1,#mermaid-svg-Ui2w7QKeahZql0cW .task2,#mermaid-svg-Ui2w7QKeahZql0cW .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-Ui2w7QKeahZql0cW .taskTextOutside0,#mermaid-svg-Ui2w7QKeahZql0cW .taskTextOutside2{fill:#000}#mermaid-svg-Ui2w7QKeahZql0cW .taskTextOutside1,#mermaid-svg-Ui2w7QKeahZql0cW .taskTextOutside3{fill:#000}#mermaid-svg-Ui2w7QKeahZql0cW .active0,#mermaid-svg-Ui2w7QKeahZql0cW .active1,#mermaid-svg-Ui2w7QKeahZql0cW .active2,#mermaid-svg-Ui2w7QKeahZql0cW .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-Ui2w7QKeahZql0cW .activeText0,#mermaid-svg-Ui2w7QKeahZql0cW .activeText1,#mermaid-svg-Ui2w7QKeahZql0cW .activeText2,#mermaid-svg-Ui2w7QKeahZql0cW .activeText3{fill:#000 !important}#mermaid-svg-Ui2w7QKeahZql0cW .done0,#mermaid-svg-Ui2w7QKeahZql0cW .done1,#mermaid-svg-Ui2w7QKeahZql0cW .done2,#mermaid-svg-Ui2w7QKeahZql0cW .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-Ui2w7QKeahZql0cW .doneText0,#mermaid-svg-Ui2w7QKeahZql0cW .doneText1,#mermaid-svg-Ui2w7QKeahZql0cW .doneText2,#mermaid-svg-Ui2w7QKeahZql0cW .doneText3{fill:#000 !important}#mermaid-svg-Ui2w7QKeahZql0cW .crit0,#mermaid-svg-Ui2w7QKeahZql0cW .crit1,#mermaid-svg-Ui2w7QKeahZql0cW .crit2,#mermaid-svg-Ui2w7QKeahZql0cW .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-Ui2w7QKeahZql0cW .activeCrit0,#mermaid-svg-Ui2w7QKeahZql0cW .activeCrit1,#mermaid-svg-Ui2w7QKeahZql0cW .activeCrit2,#mermaid-svg-Ui2w7QKeahZql0cW .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-Ui2w7QKeahZql0cW .doneCrit0,#mermaid-svg-Ui2w7QKeahZql0cW .doneCrit1,#mermaid-svg-Ui2w7QKeahZql0cW .doneCrit2,#mermaid-svg-Ui2w7QKeahZql0cW .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-Ui2w7QKeahZql0cW .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-Ui2w7QKeahZql0cW .milestoneText{font-style:italic}#mermaid-svg-Ui2w7QKeahZql0cW .doneCritText0,#mermaid-svg-Ui2w7QKeahZql0cW .doneCritText1,#mermaid-svg-Ui2w7QKeahZql0cW .doneCritText2,#mermaid-svg-Ui2w7QKeahZql0cW .doneCritText3{fill:#000 !important}#mermaid-svg-Ui2w7QKeahZql0cW .activeCritText0,#mermaid-svg-Ui2w7QKeahZql0cW .activeCritText1,#mermaid-svg-Ui2w7QKeahZql0cW .activeCritText2,#mermaid-svg-Ui2w7QKeahZql0cW .activeCritText3{fill:#000 !important}#mermaid-svg-Ui2w7QKeahZql0cW .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-Ui2w7QKeahZql0cW g.classGroup text .title{font-weight:bolder}#mermaid-svg-Ui2w7QKeahZql0cW g.clickable{cursor:pointer}#mermaid-svg-Ui2w7QKeahZql0cW g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-Ui2w7QKeahZql0cW g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-Ui2w7QKeahZql0cW .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-Ui2w7QKeahZql0cW .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-Ui2w7QKeahZql0cW .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-Ui2w7QKeahZql0cW .dashed-line{stroke-dasharray:3}#mermaid-svg-Ui2w7QKeahZql0cW #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Ui2w7QKeahZql0cW #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Ui2w7QKeahZql0cW #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-Ui2w7QKeahZql0cW #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-Ui2w7QKeahZql0cW #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Ui2w7QKeahZql0cW #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Ui2w7QKeahZql0cW #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Ui2w7QKeahZql0cW #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Ui2w7QKeahZql0cW .commit-id,#mermaid-svg-Ui2w7QKeahZql0cW .commit-msg,#mermaid-svg-Ui2w7QKeahZql0cW .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-Ui2w7QKeahZql0cW g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-Ui2w7QKeahZql0cW g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-Ui2w7QKeahZql0cW g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-Ui2w7QKeahZql0cW .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-Ui2w7QKeahZql0cW .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-Ui2w7QKeahZql0cW .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-Ui2w7QKeahZql0cW .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-Ui2w7QKeahZql0cW .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-Ui2w7QKeahZql0cW .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-Ui2w7QKeahZql0cW .edgeLabel text{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Ui2w7QKeahZql0cW .node circle.state-start{fill:black;stroke:black}#mermaid-svg-Ui2w7QKeahZql0cW .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-Ui2w7QKeahZql0cW #statediagram-barbEnd{fill:#9370db}#mermaid-svg-Ui2w7QKeahZql0cW .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-Ui2w7QKeahZql0cW .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-Ui2w7QKeahZql0cW .statediagram-state .divider{stroke:#9370db}#mermaid-svg-Ui2w7QKeahZql0cW .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-Ui2w7QKeahZql0cW .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-Ui2w7QKeahZql0cW .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-Ui2w7QKeahZql0cW .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-Ui2w7QKeahZql0cW .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-Ui2w7QKeahZql0cW .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-Ui2w7QKeahZql0cW .note-edge{stroke-dasharray:5}#mermaid-svg-Ui2w7QKeahZql0cW .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-Ui2w7QKeahZql0cW .error-icon{fill:#522}#mermaid-svg-Ui2w7QKeahZql0cW .error-text{fill:#522;stroke:#522}#mermaid-svg-Ui2w7QKeahZql0cW .edge-thickness-normal{stroke-width:2px}#mermaid-svg-Ui2w7QKeahZql0cW .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-Ui2w7QKeahZql0cW .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-Ui2w7QKeahZql0cW .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-Ui2w7QKeahZql0cW .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-Ui2w7QKeahZql0cW .marker{fill:#333}#mermaid-svg-Ui2w7QKeahZql0cW .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-Ui2w7QKeahZql0cW {color: rgba(0, 0, 0, 0.75);font: ;}

找到系统中安装的所有HII选项
为每个选项分配空间
初始化每个选项
为每个选项创建操作码

最终的操作也是创建操作码:

    HiiCreateGotoExOpCode (StartOpCodeHandle,0,gHiiDriverList[Index].PromptId,gHiiDriverList[Index].HelpId,0,(EFI_QUESTION_ID) (Index + FRONT_PAGE_KEY_DRIVER),0,&gHiiDriverList[Index].FormSetGuid,gHiiDriverList[Index].DevicePathId);

对应的操作码可能是EFI_IFR_REF_OPEFI_IFR_REF2_OPEFI_IFR_REF3_OPEFI_IFR_REF4_OP,这依赖于传入的参数值。

创建Continue/reset菜单

两者对应的都是EFI_IFR_ACTION_OP操作码,对应的实现:

/**Create continue menu in the front page.@param[in]    HiiHandle           The hii handle for the Uiapp driver.@param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.**/
VOID
UiCreateContinueMenu (IN EFI_HII_HANDLE              HiiHandle,IN VOID                        *StartOpCodeHandle)
{HiiCreateActionOpCode (StartOpCodeHandle,FRONT_PAGE_KEY_CONTINUE,STRING_TOKEN (STR_CONTINUE_PROMPT),STRING_TOKEN (STR_CONTINUE_PROMPT),EFI_IFR_FLAG_CALLBACK,0);
}/**Create Reset menu in the front page.@param[in]    HiiHandle           The hii handle for the Uiapp driver.@param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.**/
VOID
UiCreateResetMenu (IN EFI_HII_HANDLE              HiiHandle,IN VOID                        *StartOpCodeHandle)
{HiiCreateActionOpCode (StartOpCodeHandle,FRONT_PAGE_KEY_RESET,STRING_TOKEN (STR_RESET_STRING),STRING_TOKEN (STR_RESET_STRING),EFI_IFR_FLAG_CALLBACK,0);
}

从代码中可以看到,差别只在显示和QuestionId,后者在回调函数中判断其值并执行不同的操作,其代码在UiSupportLibCallbackHandler(),部分代码如下:

    switch (QuestionId) {case FRONT_PAGE_KEY_CONTINUE://// This is the continue - clear the screen and return an error to get out of FrontPage loop//*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;break;case FRONT_PAGE_KEY_LANGUAGE:*Status = LanguageChangeHandler(Value);break;case FRONT_PAGE_KEY_RESET://// Reset//gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);*Status = EFI_UNSUPPORTED;default:break;}

【UEFI实战】HII之FrontPage相关推荐

  1. UEFI实战--------HII之uni文件

    uni文件 HII的实现涉及到多种不同类型的文件,uni文件是其中最简单的一种,它用来存放各种语言的字符串以实现本地化.本节主要参考自<edk-ii-uni-specification.pdf& ...

  2. 【UEFI实战】EDK的编译流程说明

    前言 使用EDK进行UEFI开发,开始的时候很容易遇到的问题就是编译不过,并非代码的问题,而是编译环境存在异常. 本文主要介绍EDK是如何进行编译的,使用的平台是Windows.这里还想说一点,事实上 ...

  3. 【UEFI实战】LinuxBoot

    综述 LinuxBoot是一个开源的固件,用来替代UEFI BIOS加载Linux的系统. 官网是LinuxBoot. 对应的代码库位于LinuxBoot · GitHub. 另外,本文是在[UEFI ...

  4. 【UEFI实战】OS下如何查看系统相关信息

    说明 本文主要介绍OS下如何来查看系统信息,这些系统信息大多是通过BIOS上传的.这里的OS主要分为Linux和Windows两个部分来说明,前者使用的发行版系统是Ubuntu18.04,后者使用的是 ...

  5. 【UEFI实战】UART的初始化

    说明 UART全称是Universal Asynchronous Receiver/Transmitter,这里它表示的是一种实现串口通信的芯片,在整个串口系统中它的位置如下图所示: RS232 +- ...

  6. 【UEFI实战】FSP简介

    说明 在[UEFI实战]SlimBootloader简介中有说到,编译Slim Bootloader的时候需要使用到FSP,本文就是用来介绍FSP是什么,它的作用,以及如何编译等内容. 什么是FSP ...

  7. 【UEFI实战】HII之常用函数

    资源安装 HiiAddPackages 函数原型: /**Registers a list of packages in the HII Database and returns the HII Ha ...

  8. 【UEFI实战】HII之vfr文件

    vfr文件 HII的实现涉及到多种不同类型的文件,vfr文件是其中最重要的一种,它构成了界面的结构样式.本文主要参考自<edk-ii-vfr-specification.pdf>,后面简称 ...

  9. 【UEFI实战】HII之配置

    HII配置 配置数据(Configuration Settings)与HII数据库和Form浏览器的关系: 存放配置信息的NVS有两种:一种是BIOS本身的存储区,一种是外置卡的存储区. 一般情况下存 ...

最新文章

  1. [译] Spring 的分布式事务实现-使用和不使用XA — 第三部分
  2. 阿里云服务器,,外网访问公网IP不成功
  3. 7.Spring Cloud Alibaba教程:整合Dubbo实现RPC调用
  4. 【jetson nano】ubuntu- python-ssh远程控制jetson nano与单片机串口通信
  5. Java中的异步等待
  6. mysql error 1594_【MySQL】解决mysql的 1594 错误-阿里云开发者社区
  7. linux iptables找不到,centos /etc/sysconfig/下找不到iptables文件解决方法
  8. Win7下使用VFW库连接摄像头
  9. 洛谷P1130 红牌 动态规划
  10. 【课程复习+记录】最优化理论与方法
  11. python函数和代码复用思维导图_函数式编程库:Ramda函数思维导图,帮你快速选择要用的函数...
  12. 超市管理系统软件测试用例图,超市管理系统用户管理模块测试用例集.doc
  13. [机器学习、Spark]Spark机器学习库MLlib的概述与数据类型
  14. 2022年3月22日
  15. ModHOMM3 使用说明
  16. secondary namenode详解
  17. slideUp()方法和slideDown()方法
  18. 深入理解Android系统网络架构
  19. 2022年计算机保研夏令营经验总结,11所院校经历,预推免上岸北大
  20. Andoid扫码枪监听

热门文章

  1. c++如何获取字符串长度
  2. java的字母_java 英语 按字母分类(2)
  3. python中plot是什么意思_在matplotlib的plot函数中'o'是什么意思?
  4. 下拉多选框 微信小程序_微信小程序下拉框组件使用方法详解
  5. YahooUI库(YUI)简介
  6. 移动所联手南京联通推出5G产业技术创新服务基地,全面构建5G融合新生态...
  7. 计算机作文 六年级,描写电脑作文六年级
  8. mysql 临时表建索引_使用select中的索引在MySQL中创建一个临时表
  9. 微信 服务器设计,WeUI 为微信 Web 服务量身设计
  10. HDU - 1434 幸福列车 优先队列