UEFI_Driver_HII_Linux_Lab_Guide Uefi Driver Hii Linux Lab Guide

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 91

DownloadUEFI_Driver_HII_Linux_Lab_Guide Uefi Driver Hii Linux Lab Guide
Open PDF In BrowserView PDF
UEFI Driver HII Linux Lab Guide[DRAFT]

TABLE OF CONTENTS
UEFI_Driver_HII_Linux_Lab_Guide
UEFI Driver Wizard – Adding HII Labs
Lab 1. Adding Strings and Forms to Setup HII for User Configuration
a. Setup for Lab adding HII
b. Edit Driver for adding HII
Lab 2. Updating HII to Save Data Settings
Lab 3. Updating your driver to initialize data from the VFR data to the HII Database
Lab 4. Updating the Menu: Reset Button
Lab 5. Updating the Menu: Pop-up Box
Lab 6. Updating the Menu: Creating a String to Name a Saved Configuration
Lab 7. Updating the Menu: Numeric Entry
Lab 8. Updating your Driver for Interactive Call Backs
Lab 9. Add code to your driver when Call Back events occur for Interactive Items
Lab 10. Adding an Additional Form Page
Lab 11. Adding Communication from Driver to Console through HII
Lab Setup
Reference

DRAFT FOR REVIEW [11/08/2018 07:59:16]

1

UEFI Driver HII Linux Lab Guide[DRAFT]
UEFI_Driver_HII_Linux_Lab_Guide

UEFI DRIVER HII LINUX LAB GUIDE
UEFI and EDK II Base Training
Lab and Reference Guide
Assumes Ubuntu 16.04
DRAFT FOR REVIEW
11/08/2018 07:59:16
Revision 01.0

Contributed by
Laurie Jarlstrom, Intel Corporation

Acknowledgements
Redistribution and use in source (original document form) and 'compiled' forms (converted to
PDF, epub, HTML and other formats) with or without modification, are permitted provided
that the following conditions are met:
1. Redistributions of source code (original document form) must retain the above copyright
notice, this list of conditions and the following disclaimer as the first lines of this file
unmodified.
2. Redistributions in compiled form (transformed to other DTDs, converted to PDF, epub,
HTML and other formats) must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS DOCUMENTATION IS PROVIDED BY TIANOCORE PROJECT "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TIANOCORE PROJECT BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

DRAFT FOR REVIEW [11/08/2018 07:59:16]

2

UEFI Driver HII Linux Lab Guide[DRAFT]
UEFI_Driver_HII_Linux_Lab_Guide
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright (c) 2018, Intel Corporation. All rights reserved.

Revision History
Revision
01.0

Revision History
Initial release.

DRAFT FOR REVIEW [11/08/2018 07:59:16]

Date
July 2018

3

UEFI Driver HII Linux Lab Guide[DRAFT]
UEFI Driver Wizard – Adding HII Labs

UEFI DRIVER WIZARD – ADDING HII

DRAFT FOR REVIEW [11/08/2018 07:59:16]

4

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 1. Adding Strings and Forms to Setup HII for User Configuration

Lab 1. Adding Strings and Forms to Setup HII
for User Configuration
In this lab, you’ll learn how to use HII to add strings and forms to a firmware setup menu for
user configuration. Once you’ve complete this lab, your end result will match Figure 1.

Figure 1 My Wizard Driver menu with strings and forms

DRAFT FOR REVIEW [11/08/2018 07:59:16]

5

UEFI Driver HII Linux Lab Guide[DRAFT]
a. Setup for Lab adding HII

Lab 1 a. Setup for Lab adding HII
Complete Lab Setup to configure for building with OvmfPkg with QEMU.
Skip to Lab 1.b if the UEFI Driver Porting lab was completed.
1). Start with LAB 6. on Driver porting Lab solution and create a folder called
MyWizardDriver in the ~/src/edk2 workspace
2). Now, locate and open: ~/SRC/LabSampleCode\MyWizardDriver
3). Copy the following Files to ~/SRC/edk2/MyWizardDriver
ComponentName.c ComponentName.h
DriverBinding.h
HiiConfigAccess.c HiiConfigAccess.h
MyWizardDriver.c MyWizardDriver.h
MyWizardDriver.inf MyWizardDriver.uni
MyWizardDriver.vfr MyWizardDriverNVDataStruc.h
SimpleTextOutput.c SimpleTextOutput.h
4). Update src/edk2/OvmfPkg/OvmfPkgX64.dsc and add the MyWizardDriver.inf to
[Components]

section:

Hint: add to the last module in the

[Components]

section

MyWizardDriver/MyWizardDriver.inf{


DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.i

nf
}

5). Save and close the file
6). Open Terminal Command Prompt
bash$ cd ~/src/edk2

DRAFT FOR REVIEW [11/08/2018 07:59:16]

6

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII

Lab 1 b. Edit Driver for adding HII
1). Open the following files for updating:
MyWizardDriverNVDataStruc.h
MyWizardDriver.vfr
MyWizardDriver.uni
MyWizardDriver.h
MyWizardDriver.c
MyWizardDriver.inf
2). Update the MyWizardDriverNVDataStruc.h file by copying and pasting the following
GUID as shown below: This GUID is used to communicate to the HII Database and Browser
Engine
#define MYWIZARDDRIVER_FORMSET_GUID \
{ \
0x5481db09, 0xe5f7, 0x4158, 0xa5, 0xc5, 0x2d, 0xbe, 0xa4, 0x95, 0x34, 0xff \
}

3). Save MyWizardDriverNVDataStruc.h
4). Update the MyWizardDriver.vfr file. 5) Delete its contents and replace it with the
following by copying and pasting: You’re adding a reference to the GUID and to the NVRAM
storage where the configuration will be saved. In fact, you’re replacing most of the original
.vfr.

DRAFT FOR REVIEW [11/08/2018 07:59:16]

7

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII
#include "MyWizardDriverNVDataStruc.h"
formset
guid

= MYWIZARDDRIVER_FORMSET_GUID,

title

= STRING_TOKEN(STR_SAMPLE_FORM_SET_TITLE),

help

= STRING_TOKEN(STR_SAMPLE_FORM_SET_HELP),

classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
//
// Define a Buffer Storage (EFI_IFR_VARSTORE)
//
varstore MYWIZARDDRIVER_CONFIGURATION,
//varid = CONFIGURATION_VARSTORE_ID,

// This is the data structure type
// Optional VarStore ID

name

= MWD_IfrNVData,

// Define referenced name in vfr

guid

= MYWIZARDDRIVER_FORMSET_GUID;

// GUID of this buffer storage

6). Continue adding the remaining code to MyWizardDriver.vfr. This is a Enable/ Disable
question for the setup menu in the form of a Check box.

form formid = 1, title = STRING_TOKEN(STR_SAMPLE_FORM1_TITLE);
subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT);
subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT2);
//
// Define a checkbox to enable / disable the device
//
checkbox varid

= MWD_IfrNVData.MyWizardDriverChooseToEnable,

prompt

= STRING_TOKEN(STR_CHECK_BOX_PROMPT),

help

= STRING_TOKEN(STR_CHECK_BOX_HELP),

//
// CHECKBOX_DEFAULT indicate this checkbox is marked
//

with EFI_IFR_CHECKBOX_DEFAULT
//
flags

= CHECKBOX_DEFAULT ,

key

= 0,

default

= 1,

endcheckbox;
endform;
endformset;

7). Save MyWizardDriver.vfr
8). Update MyWizardDriver.uni file. You’ll add new strings to support the forms. Delete the
file’s content and replace it with the following by copying and pasting:

DRAFT FOR REVIEW [11/08/2018 07:59:16]

8

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII

#langdef en "English"
#string STR_SAMPLE_FORM_SET_TITLE

#language en

"My Wizard

Driver Sample Forms

#string STR_SAMPLE_FORM_SET_HELP

#language en

"Help for Sample Formset"

#string STR_SAMPLE_FORM1_TITLE

#language en

"My Wizard Driver"

#string STR_SUBTITLE_TEXT

#language en "My Wizard Driver Configuration"

#string STR_SUBTITLE_TEXT2

#language en "Device XYZ Configuration"

#string STR_CHECK_BOX_PROMPT

#language en "Enable My XYZ Device"

#string STR_CHECK_BOX_HELP

#language en "This is the help message for th

et"

e enable My XYZ device. Check this box to enable this device."

9). Save MyWizardDriver.uni
10). Update the MyWizardDriver.h file. Add the following HII libraries starting at
approximately line 41 (as shown below) by copying and pasting:
// Added for HII
#include 
#include 
#include 
#include 

11). To add a data structure for HII routing and access, add the following code at
approximately line 75 by copying and pasting after the “

DRAFT FOR REVIEW [11/08/2018 07:59:16]

extern

” statements:

9

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII
#define MYWIZARDDRIVER_DEV_SIGNATURE SIGNATURE_32 ('m', 'w', 'd', 'r')
// Need a Data structure for HII routing and accessing
typedef struct {
UINT32

Signature;

EFI_HANDLE

Handle;

MYWIZARDDRIVER_CONFIGURATION

Configuration;

EFI_HANDLE

DriverHandle[2];

EFI_HII_HANDLE

HiiHandle[2];

//
// Consumed protocol
//
EFI_HII_DATABASE_PROTOCOL

*HiiDatabase;

EFI_HII_STRING_PROTOCOL

*HiiString;

EFI_HII_CONFIG_ROUTING_PROTOCOL

*HiiConfigRouting;

EFI_FORM_BROWSER2_PROTOCOL

*FormBrowser2;

//
// Produced protocol
//
EFI_HII_CONFIG_ACCESS_PROTOCOL

ConfigAccess;

} MYWIZARDDRIVER_DEV;
#define MYWIZARDDRIVER_DEV_FROM_THIS(a)

CR (a, MYWIZARDDRIVER_DEV, ConfigAccess, MY

WIZARDDRIVER_DEV_SIGNATURE)
#pragma pack(1)
///
/// HII specific Vendor Device Path definition.
///
typedef struct {
VENDOR_DEVICE_PATH

VendorDevicePath;

EFI_DEVICE_PATH_PROTOCOL

End;

} HII_VENDOR_DEVICE_PATH;
#pragma pack()

DRAFT FOR REVIEW [11/08/2018 07:59:16]

10

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII

12). Save MyWizardDriver.h
13). Update MyWizardDriver.c file.
Add local definitions for the form GUID, variable name, and device path for HII at
approximately line 13 after the

#include "MyWizardDriver.h"

by coping and pasting the

following code.
In this step, you declare a local (to the module “

m

”) variable for the GUID we declared; the

NVRAM variable name; driver handles; our configuration data; and the device path support.

DRAFT FOR REVIEW [11/08/2018 07:59:16]

11

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII
// Begin code
//HII support
EFI_GUID

mMyWizardDriverFormSetGuid = MYWIZARDDRIVER_FORMSET_GUID;

CHAR16

mIfrVariableName[] = L"MWD_IfrNVData";

EFI_HANDLE

mDriverHandle[2] = {NULL, NULL};

MYWIZARDDRIVER_DEV

*PrivateData = NULL;

// HII support for Device Path
HII_VENDOR_DEVICE_PATH

mHiiVendorDevicePath = {

{
{
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
{
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
}
},
MYWIZARDDRIVER_FORMSET_GUID
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{
(UINT8) (END_DEVICE_PATH_LENGTH),
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
}
}
};
// end code

14). Locate EFI_STATUS within the function
MyWizardDriver.c

MyWizardDriverDriverEntryPoint

in the

file (approx. Line 184) and add HII local definitions by copying and pasting

(as shown below):
// HII Locals
EFI_HII_PACKAGE_LIST_HEADER

*PackageListHeader;

EFI_HII_DATABASE_PROTOCOL

*HiiDatabase;

EFI_HII_HANDLE

HiiHandle[2];

EFI_STRING

ConfigRequestHdr;

UINTN

BufferSize;

DRAFT FOR REVIEW [11/08/2018 07:59:16]

12

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII

15). Locate the ASSERT_EFI_ERROR (Status); statement and the line: // Retrieve HII
Package List Header on ImageHandle (approximately line 202). Now, add the following
code to install the configuration access protocol (produced) by copying and pasting (as
shown below) before the line: // Retrieve HII Package List Header on ImageHandle
//Now do HII Stuff
// Initialize the local variables.
ConfigRequestHdr = NULL;
// Initialize driver private data
PrivateData = AllocateZeroPool (sizeof (MYWIZARDDRIVER_DEV));
if (PrivateData == NULL) {
return EFI_OUT_OF_RESOURCES;
}
PrivateData->Signature = MYWIZARDDRIVER_DEV_SIGNATURE;
PrivateData->ConfigAccess.ExtractConfig = MyWizardDriverHiiConfigAccessExtractConfig
;
PrivateData->ConfigAccess.RouteConfig = MyWizardDriverHiiConfigAccessRouteConfig;
PrivateData->ConfigAccess.Callback = MyWizardDriverHiiConfigAccessCallback;
//
// Publish sample Fromset and config access
//
Status = gBS->InstallMultipleProtocolInterfaces (
&mDriverHandle[0],
&gEfiDevicePathProtocolGuid,
&mHiiVendorDevicePath,
&gEfiHiiConfigAccessProtocolGuid,
&PrivateData->ConfigAccess,
NULL
);
ASSERT_EFI_ERROR (Status);
PrivateData->DriverHandle[0] = mDriverHandle[0];
// end code

DRAFT FOR REVIEW [11/08/2018 07:59:16]

13

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII

16). Next, add code to register a list of HII packages in the HII Database with the HII device
path. This requires you to replace existing code (see below) by copying and pasting the new
code at approx. line 265.
Old Code

mDriverHandle[0],
&HiiHandle[0]

DRAFT FOR REVIEW [11/08/2018 07:59:16]

14

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII

New Code

17). Next, you’ll add code to initialize the My Wizard Driver NVRAM variable by copying and
pasting the following code before the
ImageHandle

// Install Driver Supported EFI Version Protocol onto

comment (as shown below at approximately line 273):

// Begin code
PrivateData->HiiHandle[0] = HiiHandle[0];
BufferSize = sizeof (MYWIZARDDRIVER_CONFIGURATION);
// IF driver is not part of the Platform then need to get/set defaults for the NVRAM
configuration that the driver will use.
Status = gRT->GetVariable (
mIfrVariableName,
&mMyWizardDriverFormSetGuid,
NULL,
&BufferSize,
&PrivateData->Configuration
);
if (EFI_ERROR (Status)) {

// Not definded yet so add it to the NV Variables.

// zero out buffer
ZeroMem (&PrivateData->Configuration, sizeof (MYWIZARDDRIVER_CONFIGURATION));
Status = gRT->SetVariable(
mIfrVariableName,
&mMyWizardDriverFormSetGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (MYWIZARDDRIVER_CONFIGURATION),
&PrivateData->Configuration

//

buffer is 000000

now

);
}
// end code

DRAFT FOR REVIEW [11/08/2018 07:59:16]

15

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII

18). Save MyWizardDriver.c
19). Now onto the final file, MyWizardDriver.inf. Add the following protocols in the [protocols]
section that are being used by copying and pasting (as shown below):
gEfiHiiStringProtocolGuid

## CONSUMES

gEfiHiiConfigRoutingProtocolGuid

## CONSUMES

gEfiFormBrowser2ProtocolGuid

## CONSUMES

gEfiHiiDatabaseProtocolGuid

## CONSUMES

20). Save the MyWizardDriver.inf file. All the files should be saved at this point.
21). Add MyWizardDriver.inf to the OvmfPkgX64.dsc(See Lab 2 building MyWizardDriver
from the Driver Porting Lab)

DRAFT FOR REVIEW [11/08/2018 07:59:16]

16

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

2. Copy MyWizardDriver.efi to hda-contents
bash$ cd ~/run-ovmf/hda-contents
bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver.efi .

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type fs0:
5. Type Load MyWizardDriver.efi and Press “Enter”
This will load your driver into memory

6. Type exit
7. Now at the setup front page menu, select “Device Manager”

8. Press “Enter” to enter “Device Manager”
9. Inside the Device Manager menu press the down to “My Wizard Driver Sample
Formset”** Press "Enter"

DRAFT FOR REVIEW [11/08/2018 07:59:16]

17

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII
Press "Enter"

Note: Notice that your form is now displayed with a choice to enable your device. Also
notice the titles and help strings that are in the .UNI file you edited.
At this point since the HII configuration routing functions are not functional the values
(Enable/ Disable) will not be saved to NVRAM. The next lab will update the HII Extract,
Route, and call back functions for the HII configuration routing protocol your driver will
produce.
10. Press the space bar to Enable and Disable the “Enable My XYZ Device”
11. Press F10 to attempt to save

DRAFT FOR REVIEW [11/08/2018 07:59:16]

18

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII

Note: You’re not able to save the data changes at this point.
12. Press “Enter”**
13. Press “Escape”, and then “Y” to exit*
14. To Exit the “Device Manager” Page: Press “Escape”

15. Press Up Arrow to “Continue”**

16. At the Shell prompt type Reset

17. Exit QEMU

DRAFT FOR REVIEW [11/08/2018 07:59:16]

19

UEFI Driver HII Linux Lab Guide[DRAFT]
b. Edit Driver for adding HII
You’ve completed the first lab and added strings and forms to setup HII for user
configuration. However, the data is not saved to NVRAM. In the next lab, you’ll learn how
to update HII to save data to NVRAM.
For any build issues copy the solution files from ~/FW/LabSolutions/LessonE.1

End of Lab 1

DRAFT FOR REVIEW [11/08/2018 07:59:16]

20

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings

Lab 2. Updating HII to Save Data Settings
In this lab, you’ll learn how to modify and update your driver’s HII code to save the users
settings into NVRAM. The UEFI Driver Wizard created the protocols for your driver to update
and interface with the HII browser engine and database. The HII configuration access
Protocol functions for MyWizardDriver are in the file
~src/edk2/MyWizardDriver/HiiConfigAccess.c. This next lab will install these protocols and
update them to save the user data from the HII menus into NVRAM.
1. Update the

MyWizardDriver.c

file

Your driver will need to keep track of the consumed protocols in it’s own data structure
so it will need to declare local pointers to these and then store them in its own private
context data structure.
2. Add the following local variable declarations in the function
MyWizardDriverDriverEntryPoint

Entry Point (as shown below Approx. line 185 ):

EFI_HII_STRING_PROTOCOL

*HiiString;

EFI_FORM_BROWSER2_PROTOCOL

*FormBrowser2;

EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;

3. Add the following code to locate and store consumed protocols before the
sample Fromset and config access

// Publish

comment (as shown below Approx. line 227):

The reason is to Locate the Hii Database, Hii String, Hii Form browser and config
routing protocols and store their pointers into the Private context data structure for your
driver to access.

DRAFT FOR REVIEW [11/08/2018 07:59:16]

21

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings
//Begin code
//
// Locate Hii Database protocol
//
Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiData
base);
if (EFI_ERROR (Status)) {
return Status;
}
PrivateData->HiiDatabase = HiiDatabase;
//
// Locate HiiString protocol
//
Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString
);
if (EFI_ERROR (Status)) {
return Status;
}
PrivateData->HiiString = HiiString;
//
// Locate Formbrowser2 protocol
//
Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBr
owser2);
if (EFI_ERROR (Status)) {
return Status;
}
PrivateData->FormBrowser2 = FormBrowser2;
//
// Locate ConfigRouting protocol
//
Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &Hi
iConfigRouting);
if (EFI_ERROR (Status)) {
return Status;
}
PrivateData->HiiConfigRouting = HiiConfigRouting;
//End code

DRAFT FOR REVIEW [11/08/2018 07:59:16]

22

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings

4). Since the Hii Database Protocol was located earlier in the code with the previous code
insertion and is no longer necessary, comment out the old OpenProtocol code with the
“

//

” (approx. lines 289-298, as shown below) and add the comment "

Make sure not to comment out the second “

if (!EFI_ERROR (Status)) {

DRAFT FOR REVIEW [11/08/2018 07:59:16]

//

" Done above

”

23

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings

Note: The earlier

LocateProtocol

code already found the pointer to the Hii Database

protocol and stored it to the local pointer variable

HiiDatabase

.

When we added the driver-consumed protocols, we searched via

LocateProtocol

for the Hii

Database pointer function. Since we did it above we’re now commenting out this code.
5). Comment out the matching “

}

” with “

//

” to the if statement (as shown below at

approx. line 310):
6). Save MyWizardDriver.c
7). Open ~src/edk2/MyWizardDriver/HiiConfigAccess.c.
The Driver Wizard only made dummy functions for the extract, route and callback functions.
In order to save the Data passed into the forms from the Hii Browser engine, you will need to
port these functions to be functional.
8). Add the following extern statements for the form GUID and the NVRam variable (as
shown below) these are global to the driver module only hence the beginning lower case “m”
is the standard for a global for a module :
extern EFI_GUID

mMyWizardDriverFormSetGuid;

extern CHAR16

mIfrVariableName[];

DRAFT FOR REVIEW [11/08/2018 07:59:16]

24

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings

9). Locate

MyWizardDriverHiiConfigAccessExtractConfig

EFI_NOT_FOUND

and replace line 108, “

return

”, with the following code spread over Next pages:

//Begin code
EFI_STATUS

Status;

UINTN

BufferSize;

MYWIZARDDRIVER_DEV

*PrivateData;

EFI_HII_CONFIG_ROUTING_PROTOCOL

*HiiConfigRouting;

EFI_STRING

ConfigRequest;

EFI_STRING

ConfigRequestHdr;

UINTN

Size;

BOOLEAN

AllocatedRequest;

if (Progress == NULL || Results == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Initialize the local variables.
//
ConfigRequestHdr

= NULL;

ConfigRequest

= NULL;

Size

= 0;

*Progress

= Request;

AllocatedRequest

= FALSE;

PrivateData = MYWIZARDDRIVER_DEV_FROM_THIS (This);
HiiConfigRouting = PrivateData->HiiConfigRouting;
//
// Get Buffer Storage data from EFI variable.
// Try to get the current setting from variable.
//
BufferSize = sizeof (MYWIZARDDRIVER_CONFIGURATION);
Status = gRT->GetVariable (
mIfrVariableName,
&mMyWizardDriverFormSetGuid,
NULL,
&BufferSize,
&PrivateData->Configuration
);
if (EFI_ERROR (Status)) {

DRAFT FOR REVIEW [11/08/2018 07:59:16]

25

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings
return EFI_NOT_FOUND;
}
if (Request == NULL) {
DEBUG ((DEBUG_INFO, "\n:: Inside of Extract Config and Request == Null "));
} else {
ConfigRequest = Request;
}
//
// Convert buffer data to  by helper function BlockToConfig()
//
Status = HiiConfigRouting->BlockToConfig (
HiiConfigRouting,
ConfigRequest,
(UINT8 *) &PrivateData->Configuration,
BufferSize,
Results,
Progress
);
//
// Free the allocated config request string.
//
if (AllocatedRequest) {
FreePool (ConfigRequest);
}
//
// Set Progress string to the original request string.
//
if (Request == NULL) {
*Progress = NULL;
} else if (StrStr (Request, L"OFFSET") == NULL) {
*Progress = Request + StrLen (Request);
}
return Status;
// End code

10). Now locate
with “

MyWizardDriverHiiConfigAccessRouteConfig

return EFI_NOT_FOUND

and replace line at approx. 228,

”, with the following code:

//Begin code
EFI_STATUS

Status;

UINTN

BufferSize;

MYWIZARDDRIVER_DEV

*PrivateData;

EFI_HII_CONFIG_ROUTING_PROTOCOL

*HiiConfigRouting;

DRAFT FOR REVIEW [11/08/2018 07:59:16]

26

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings

if (Configuration == NULL || Progress == NULL) {
return EFI_INVALID_PARAMETER;
}
PrivateData = MYWIZARDDRIVER_DEV_FROM_THIS (This);
HiiConfigRouting = PrivateData->HiiConfigRouting;
*Progress = Configuration;
//
// Get Buffer Storage data from EFI variable
//
BufferSize = sizeof (MYWIZARDDRIVER_CONFIGURATION);
Status = gRT->GetVariable (
mIfrVariableName,
&mMyWizardDriverFormSetGuid,
NULL,
&BufferSize,
&PrivateData->Configuration
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Convert  to buffer data by helper function ConfigToBlock()
//
BufferSize = sizeof (MYWIZARDDRIVER_CONFIGURATION);
Status = HiiConfigRouting->ConfigToBlock (
HiiConfigRouting,
Configuration,
(UINT8 *) &PrivateData->Configuration,
&BufferSize,
Progress
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Store Buffer Storage back to EFI variable
//
Status = gRT->SetVariable(
mIfrVariableName,
&mMyWizardDriverFormSetGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (MYWIZARDDRIVER_CONFIGURATION),
&PrivateData->Configuration
);
DEBUG ((DEBUG_INFO, "\n:: ROUTE CONFIG Saving the configuration to NVRAM \n"
));
return Status;

DRAFT FOR REVIEW [11/08/2018 07:59:16]

27

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings

//return EFI_NOT_FOUND;
//end code

11). Lastly, locate MyWizardDriverHiiConfigAccessCallback and replace at approx.** line
326, “return EFI_UNSUPPORTED**;”, with the following code:

//Begin code
MYWIZARDDRIVER_DEV

*PrivateData;

EFI_STATUS

Status;

EFI_FORM_ID

FormId;

DEBUG ((DEBUG_INFO, "\n:: START Call back ,Question ID=0x%08x Type=0x%04x Action=0
x%04x", QuestionId, Type, Action));

if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_B
ROWSER_ACTION_FORM_CLOSE))||
(ActionRequest == NULL)) {
return EFI_INVALID_PARAMETER;
}

FormId = 0;
Status = EFI_SUCCESS;
PrivateData = MYWIZARDDRIVER_DEV_FROM_THIS (This);
return Status;
//end code

12). Save HiiConfigAccess.c

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

DRAFT FOR REVIEW [11/08/2018 07:59:16]

28

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings
2. Copy MyWizardDriver.efi to hda-contents
bash$ cd ~/run-ovmf/hda-contents
bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver.efi .

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type fs0:
5. Type Load MyWizardDriver.efi
6. Press “Enter”

7. Type exit
8. Now at the setup front page menu, select “Device Manager”

9. Press “Enter” to enter “Device Manager”
10. Inside the Device Manager menu press the down to “My Wizard Driver Sample
Formset”** Press "Enter"

Press "Enter"

DRAFT FOR REVIEW [11/08/2018 07:59:16]

29

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings

Note: Once you hit “Enter”, notice that your form is now displayed with a choice to
enable your Device. Also notice the titles and help strings that are in the .UNI file you
edited.
11. Test by Press the space bar to Enable and Disable the “Enable My XYZ Device” to
change its value from:
Note: Notice the “

[X]

to

[ ]

Configuration changed

” message at the menu bottom.

12. Press “F10”
13. Press “Escape” to exit
14. Press “Escape” to exit the “Device Manager” Page
15. Press Up Arrow to “Continue”

16. Press “Enter”
17. At the Shell Prompt type

Shell> dmpstore -all

Notice that enable is selected and saved in NVRam as the value of 0x00:

Because our data structure in

MyWizardDriverNVDataStruc.h

variable name

of type

MWD_IfrNVData

is stored in NVRAM with the

MYWIZARDDRIVER_CONFIGURATION

DRAFT FOR REVIEW [11/08/2018 07:59:16]

, we can see the

30

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 2. Updating HII to Save Data Settings
changes from our menu accessing through our HII forms.
Notice that the enable/disable byte is the last byte in data structure
MWD_IfrNVData.MyWizardDriverChooseToEnable

where

00 == disable

and

01 == enable

.

18. Type Reset

1. Exit Qemu

For any build issues copy the solution files from ~/Fw/LabSolutions/LessonE.2
NOTE: Del Directory ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver before
the Build command to build the MyWizardDriver Clean

End of Lab 2

DRAFT FOR REVIEW [11/08/2018 07:59:16]

31

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 3. Updating your driver to initialize data from the VFR data to the HII Database

Lab 3. Updating your driver to initialize data
from the VFR data to the HII Database
In this lab, you’ll learn how to update your driver to initialize the data according to the
defaults set in the .VFR file. Thus when the user enters your driver’s menu for the first time,
the values will display the defaults according to the .VFR file settings. You will also learn the
rich set of HII function calls that are part of the

MdeModulePkg

in the

HiiLib

by reviewing

the “MdeModulePkg Document.chm”.

Lab 3a. Add HII Library Calls to Your Driver
For this lab you will update the following files: MyWizardDriver.inf, MyWizardDriver.h, and
MyWizardDriver.c
1. Update the MyWizardDriver.inf file
2. Add the following package (as shown below):
The HII Library in the MdeModulePkg has many functions to help with Communication
to/from the Hii Database and Hii forms. One function call HiiSetToDefaults will compare
the default settings from the .VFR file and update the driver’s configuration buffer
according to the settings in the .VFR file.
MdeModulePkg/MdeModulePkg.dec

Note: For other functions from the HII Library,
open the .chm file “MdeModulePkg Document.chm” and search for

HiiLib.h

.

3). Add the following library class (as shown below):
HiiLib

4). Save MyWizardDriver.inf
5). Update the MyWizardDriver.h file

DRAFT FOR REVIEW [11/08/2018 07:59:16]

32

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 3. Updating your driver to initialize data from the VFR data to the HII Database
6). Add the following code (as shown below):
#include 

7). Save MyWizardDriver.h
8). Update the MyWizardDriver.c file
9). Add Locals: first add 2 locals for your drivers configuration buffer and a boolean flag
from the Hii Library calls
Add the following at Approx. Line 190.
MYWIZARDDRIVER_CONFIGURATION

*Configuration;

BOOLEAN

ActionFlag;

10). Add the following to the MyWizardDriverDriverEntryPoint entry point funtion to line 319,
approximately after “

BufferSize =

” as shown below

DRAFT FOR REVIEW [11/08/2018 07:59:16]

33

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 3. Updating your driver to initialize data from the VFR data to the HII Database
// Begin code
//
// Initialize configuration data
//
Configuration = &PrivateData->Configuration;
ZeroMem (Configuration, sizeof (MYWIZARDDRIVER_CONFIGURATION));
//
// Try to read NV config EFI variable first
//
ConfigRequestHdr = HiiConstructConfigHdr (&mMyWizardDriverFormSetGuid, mIfrVariableN
ame, mDriverHandle[0]);
ASSERT (ConfigRequestHdr != NULL);
// End code

11). Modify the following lines:
@~338

: remove: “

@~342

: remove line:

&PrivateData->

” from the “

&PrivateData->Configuration

”

ZeroMem (&PrivateData->Configuration, sizeof

(MYWIZARDDRIVER_CONFIGURATION));
@~347

: remove: “

&PrivateData->

12). Add the following code to the

” from the “

&PrivateData->Configuration

MyWizardDriverDriverEntryPoint

”

entry point code at

approximately line 349 before
// Install Driver Supported EFI Version Protocol onto ImageHandle

DRAFT FOR REVIEW [11/08/2018 07:59:16]

You’re deleting the “

}

"

34

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 3. Updating your driver to initialize data from the VFR data to the HII Database
and replacing it with the following code (as shown below). With this replacement we are
adding an “
Note the “

else

}

a duplicate “

” to the “

if

” statement:

” on line 361 is still matching the initial if statement. Make sure you do not have
}

”

//Begin code
//
// EFI variable for NV config doesn't exist, we should build this variable
// based on default values stored in IFR
//
ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
ASSERT (ActionFlag);
} else {
//
// EFI variable does exist and Validate Current Setting
//
ActionFlag = HiiValidateSettings (ConfigRequestHdr);
ASSERT (ActionFlag);
}

// Match if (EFI_ERROR (Status))

FreePool (ConfigRequestHdr);
// end HII
// End code

13). Save the MyWizardDriver.c file

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)

DRAFT FOR REVIEW [11/08/2018 07:59:16]

35

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 3. Updating your driver to initialize data from the VFR data to the HII Database
bash$ cd ~/src/edk2
bash$ build

2. Copy MyWizardDriver.efi to hda-contents
bash$ cd ~/run-ovmf/hda-contents
bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver.efi .

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type fs0:
5. Type Load MyWizardDriver.efi and then Press “Enter”

6. Type exit
7. Now at the setup front page menu, select “Device Manager”

8. Press “Enter” to enter “Device Manager”
9. Inside the Device Manager menu press the down to “My Wizard Driver Sample
Formset”

10. Press “Enter”

DRAFT FOR REVIEW [11/08/2018 07:59:16]

36

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 3. Updating your driver to initialize data from the VFR data to the HII Database

11. Press “Escape” to exit
12. Press “Escape” to Exit the “Device Manager” Page
13. Press Up Arrow to “Continue” and then Press “Enter”

14. Type "

Reset

"

15. Exit QEMU
For any build issues copy the solution files from ~/FW/LbSolutions/LessonE.3 NOTE: Del
Directory ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver before the Build
command to build the MyWizardDriver Clean

Lab 3b. Add your Driver to the platform
As of now, your driver needs to be soft loaded each time from the shell prompt. In this lab,
you’ll update the platform .FDF file to force your driver to load as part of the platform UEFI
driver.
1. Open to update: ~/src/edk2/OvmfPkg/OvmfPkgX64.Fdf
2. Add the following code (as shown below before “

!if $(BUILD_NEW_SHELL) == TRUE

” ):

INF MyWizardDriver/MyWizardDriver.inf

DRAFT FOR REVIEW [11/08/2018 07:59:16]

37

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 3. Updating your driver to initialize data from the VFR data to the HII Database
3. Save ~/src/edk2/OvmfPkg/OvmfPkgX64.Fdf

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

2. Copy the Note:
naming it

OVMF.fd

BIOS image created from the

build

to the run-ovmf directory

bios.bin

bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type "

Exit

"

5. Now at the setup front page menu, select “Device Manager”

6. Press “Enter” to enter “Device Manager”
7. Inside the Device Manager menu Notice that the My Wizard Driver Sample Formset is
added without having to issue the “Load” command from the shell prompt.

DRAFT FOR REVIEW [11/08/2018 07:59:16]

38

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 3. Updating your driver to initialize data from the VFR data to the HII Database

8. Press “Escape” to exit the “Device Manager” Page
9. Press Up Arrow to “Continue”

10. Press “Enter”
11. Type "

Reset

"

12. Exit QEMU

For any build issues copy the solution files from ~/FW/LbSolutions/LessonE.3
NOTE: Del Directory ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver before
the Build command to build the MyWizardDriver Clean

End of Lab 3

DRAFT FOR REVIEW [11/08/2018 07:59:16]

39

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 3. Updating your driver to initialize data from the VFR data to the HII Database

DRAFT FOR REVIEW [11/08/2018 07:59:16]

40

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 4. Updating the Menu: Reset Button

Lab 4. Updating the Menu: Reset Button
In this lab, you’ll learn how to add a resetbutton to your driver’s form menu. It’s time to add
more configuration fields to your menu, enabling users to modify more fields now that you’ve
built a driver that 1) saves data from forms into NVRAM 2) updates data from the .VFR
forms and 3) builds into the platform drivers.
The next set of labs will update .VFR,

MyWizardDriver.vfr

, and UNI

MyWizardDriver.uni

string files to incrementally add a reset button (Lab 4), pop-up box (Lab 5), string name (Lab
6), and numeric hex value (Lab 7) to your driver’s form menu:
1). Update the MyWizardDriver.vfr file 2). Add the following code (as shown below after the
“GUID” definition Apprx. Line 29):

prompt =

MyStandardDefault

,

STRING_TOKEN(STR_STANDARD_DEFAULT_PROMPT),

attribute = 0x0000;

// Default ID: 0000 standard default

3). Add the folowing code before the “

endform

” (as shown below Approx. Line 55):

resetbutton
defaultstore = MyStandardDefault,
prompt

= STRING_TOKEN(STR_STANDARD_DEFAULT_PROMPT_RESET),

help

= STRING_TOKEN(STR_STANDARD_DEFAULT_HELP),

endresetbutton;

4). Save MyWizardDriver.vfr
5). Update the MyWizardDriver.uni file

DRAFT FOR REVIEW [11/08/2018 07:59:16]

41

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 4. Updating the Menu: Reset Button
6). Add the following strings at the end of the file to support the “

STR_

“ referenced added in

the .vfr file:
#string STR_STANDARD_DEFAULT_PROMPT

#language en "Standard Default"

#string STR_STANDARD_DEFAULT_PROMPT_RESET
#string STR_STANDARD_DEFAULT_HELP

#language en "Reset to Standard Default"

#language en "This will reset all the Questions

to their standard default value"

7). Save MyWizardDriver.uni

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

2. Copy the
naming it

OVMF.fd

BIOS image created from the

build

to the run-ovmf directory

bios.bin

bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type exit

1. Now at the setup front page menu, select “Device Manager”
2. Press “Enter” to enter “Device Manager”
3. Inside the Device Manager menu press the down arrow to “My Wizard Driver Sample
Formset” Press "Enter"
4. Access the My Wizard Driver menu and notice the item “Reset to Standard Default”

DRAFT FOR REVIEW [11/08/2018 07:59:16]

42

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 4. Updating the Menu: Reset Button

5. Press Down Arrow to “Reset to Standard Default”
6. Press “Enter" to select
7. Notice the “Configuration changed” message at the bottom of the menu
8. To Exit Press “Escape” then “Y”
9. To Exit the “Device Manager” Page: Press “Escape”
10. Press Up Arrow to “Continue”
Observe: Notice that since this change requires a reset, the shell will exit out

completely.
11. Press “Enter” to reset
12. Exit QEMU

For any build issues copy the solution files from ~/FW/LabSolutions/LessonE.4
NOTE: Delete Directory ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver
before the Build command to build the MyWizardDriver Clean

DRAFT FOR REVIEW [11/08/2018 07:59:16]

43

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 4. Updating the Menu: Reset Button

End of Lab 4

DRAFT FOR REVIEW [11/08/2018 07:59:16]

44

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 5. Updating the Menu: Pop-up Box

Lab 5. Updating the Menu: Pop-up Box
In this lab, you’ll learn how to add a pop-up box to your driver’s form menu by using the
“oneof” VFR term. We will also only update the MyWizardDriver.vfr and MyWizardDriver.uni
files.

Figure 5 My Wizard Driver with a pop-up box
Background Information The VFR term “oneof” will declare a pop-up menu. The user then
selects one field that will dictate the value stored in the NVRAM variable. Looking at Figure 5
above, there are three values:
Value

Display

String token

0

500 Hex

STR_ONE_OF_TEXT3

1

480 Hex

STR_ONE_OF_TEXT2

2

400 Hex

STR_ONE_OF_TEXT1

For this lab you will add code to give your driver menu a pop-up menu item by defining a
“oneof” item. Also, if the device is “disabled”, then use the VFR term “grayoutif” statement
so that the pop-up menu is not accessible and cannot be changed. The browser engine will

DRAFT FOR REVIEW [11/08/2018 07:59:16]

45

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 5. Updating the Menu: Pop-up Box
use the configuration variable
0x0

MWD_IfrNVData.MyWizardDriverChooseToEnable

with a value of

to determine if the device is enabled or disabled

1. Update the MyWizardDriver.vfr file
2. Add the following code before the “

resetbutton

” statement (approximately line 53)

// Begin code
//
// Define oneof (EFI_IFR_ONE_OF)
//
grayoutif

ideqval MWD_IfrNVData.MyWizardDriverChooseToEnable == 0x0;

oneof name = MyOneOf2,

// Define reference name for

Question
varid

= MWD_IfrNVData.MyWizardDriverBaseAddress,

// Use "DataStructure.Member" to reference Buffer Storage
prompt

= STRING_TOKEN(STR_ONE_OF_PROMPT),

help

= STRING_TOKEN(STR_ONE_OF_HELP),

//
// Define an option (EFI_IFR_ONE_OF_OPTION)
//
option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value = 0x0, flags = 0;
option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 0x1, flags = 0;
//
// DEFAULT indicate this option will be marked with
//

EFI_IFR_OPTION_DEFAULT

//
option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0x2,
flags = DEFAULT;
endoneof;
endif;
// end code

DRAFT FOR REVIEW [11/08/2018 07:59:16]

46

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 5. Updating the Menu: Pop-up Box

3. Save the MyWizardDriver.vfr file
4. Update the MyWizardDriver.uni file
5. Add the following code to the end of the file (as shown below):
// begin code
#string STR_ONE_OF_PROMPT

#language en "Select Base Address"

#string STR_ONE_OF_HELP

#language en "Select a Base address of 400, 480

or 500 Hex.

Values 0,1 or 2(default) is stored in the NVRAM Data"

#string STR_ONE_OF_TEXT1

#language en "400 Hex"

#string STR_ONE_OF_TEXT2

#language en "480 Hex"

#string STR_ONE_OF_TEXT3

#language en "500 Hex"

// end code

6). Save MyWizardDriver.uni

Build and test MyWizardDriver

DRAFT FOR REVIEW [11/08/2018 07:59:16]

47

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 5. Updating the Menu: Pop-up Box
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

2. Copy the
naming it

OVMF.fd

BIOS image created from the

build

to the run-ovmf directory

bios.bin

bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type exit

5. Now at the setup front page menu, select “Device Manager”
6. Inside the Device Manager menu press the down arrow to “My Wizard Driver Sample
Formset” Press "Enter"
7. Down Arrow to “Select Base Address”

Notice the Pop up menu
8. Select “480 Hex” then press "Enter"
Observe: the “Configuration changed” message at the bottom

DRAFT FOR REVIEW [11/08/2018 07:59:16]

48

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 5. Updating the Menu: Pop-up Box

9. Test the “

grayoutif

” by selecting “Enable My XYZ Device” then press the “Space” bar

to toggle off or “Disabled”.
Notice the “Select Base Address” is now grayed out and not Selectable.

10. Press “Space” again to Enable
11. To Exit Press “Escape” then “Y” or “F10” then “Escape”
12. To Exit the “Device Manager” Page: Press “Escape”
13. Press Up Arrow to “Continue”
14. At the Shell Prompt type: "

dmpstore -all

DRAFT FOR REVIEW [11/08/2018 07:59:16]

"

49

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 5. Updating the Menu: Pop-up Box

15. Observe file MyWizardDriverNVDataStruc.h and the NVRAM

MWD_IfrNVData

variable.

By updating MyWizardDriverNVDataStruc.h, our data structure stored in NVRAM is
named

MWD_IfrNVData

of type

MYWIZARDDRIVER_CONFIGURATION

.

Notice that the base address byte is the next to the last byte in the data structure
MWD_IfrNVData.MyWizardDriverBaseAddress

where

02 == 400H

,

01 == 480H

, and

00 ==

500H

Notice the NVRAM Variable with the value of

480H

will have a true value of

01

.

16. Type “reset” at the Shell prompt

17. Exit QEMU

For any build issues copy the solution files from ~/Fw/LabSolutions/LessonE.5
NOTE: Delete Directory ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver
before the Build command to build the MyWizardDriver Clean

End of Lab 5

DRAFT FOR REVIEW [11/08/2018 07:59:16]

50

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 6. Updating the Menu: Creating a String to Name a Saved Configuration

Lab 6. Updating the Menu: Creating a String to
Name a Saved Configuration
In this lab, you’ll create a string to name a saved configuration that will be stored into the
NVRAM variable space. This lab uses the VFR term “string” to prompt the user to enter a
string value. The VFR can determine the minimum and maximum number of characters of
the string length with the terms “

minsize

” and “

enable/disable switch, the VFR can use the “

maxsize

grayoutif

”. Since there is also an

” term again to allow or disallow

changes to this field.

Figure 6 : Menu with a string item
1. Update the MyWizardDriver.vfr file
2. Add the following code to the location at approx. line 77 and before the “

resetbutton

”

item (as shown below):

DRAFT FOR REVIEW [11/08/2018 07:59:16]

51

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 6. Updating the Menu: Creating a String to Name a Saved Configuration
//
// Define a string (EFI_IFR_STRING) to name the configuration in the
// NVRAM variable
//
grayoutif
string

ideqval MWD_IfrNVData.MyWizardDriverChooseToEnable == 0x0;
varid

= MWD_IfrNVData.MyWizardDriverStringData,

prompt

= STRING_TOKEN(STR_MY_STRING_PROMPT),

help

= STRING_TOKEN(STR_MY_STRING_HELP),

minsize

= 3,

maxsize

= 20,

endstring;
endif;

3. Save MyWizardDriver.vfr
4. Update MyWizardDriver.uni
5. Add the following code to the bottom of the file:

#string STR_MY_STRING_PROMPT

#language en "Name of Configuration"

#string STR_MY_STRING_HELP

#language en "Enter a name for this configurati

on. This string can is 3 to 20 characters"

DRAFT FOR REVIEW [11/08/2018 07:59:16]

52

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 6. Updating the Menu: Creating a String to Name a Saved Configuration

6). Save MyWizardDriver.uni

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

2. Copy the
naming it

OVMF.fd

BIOS image created from the

build

to the run-ovmf directory

bios.bin

bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type exit

5. Now at the setup front page menu, select “Device Manager”
6. Inside the Device Manager menu press the down arrow to “My Wizard Driver Sample
Formset” Press "Enter"
7. Select “Name of Configuration” then Press “Enter”
Notice the string text pop up menu gets displayed.

DRAFT FOR REVIEW [11/08/2018 07:59:16]

53

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 6. Updating the Menu: Creating a String to Name a Saved Configuration

8. Test the “

minsize

” by only typing your choice of a two character string. Then Press

“Enter”
Notice the an error message validating that you need to enter at least three or more
characters.

9. Press “Enter” to clear the message
10. Press “Enter” again to re-enter pop up menu
11. Test by typing more than “

maxsize

” of 20 characters** Then Press “Enter” .

Notice** that the Browser only allows the maximum number of 20 characters to be
entered with a forced stop. There is no error message but no more characters are
allowed to be typed into the pop up menu.

DRAFT FOR REVIEW [11/08/2018 07:59:16]

54

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 6. Updating the Menu: Creating a String to Name a Saved Configuration

12. Press “Enter”
Notice that the “Configuration changed” message is displayed

13. Test the

grayoutif

by selecting “Enable My XYZ Device”

14. Press the “Spacebar” to toggle off/disable. Then Press the “Spacebar” again to Enable.
Notice that the “Select Base Address” and “Name of Configruation” fields are now
grayed out and not selectable

DRAFT FOR REVIEW [11/08/2018 07:59:16]

55

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 6. Updating the Menu: Creating a String to Name a Saved Configuration

15. Press “F10” to save.
16. Press “Escape” to exit
17. Press “Escape” to exit the “Device Manager”
18. Select “Continue” and then Press “Enter”
19. At the Shell Prompt, type

dmpstore -all

Notice the unicode string “

12345678901234567890

” (or the 20 character value you typed)

is now stored because you entered those characters in the HII form menu. This is
because the file

WizardDriverNVDataStruc.h

with the GUID define name

MWD_IfrNVData

has the data structure stored in NVRAM
of type

MYWIZARDDRIVER_CONFIGURATION

.

Notice that string data is the first 20 bytes in the data structure
MWD_IfrNVData.MyWizardDriverStringData

.

20. Type “reset” and then “Enter" at the Shell prompt

21. Exit QEMU

For any build issues copy the solution files from ~/Fw/LabSolutions/LessonE.6

DRAFT FOR REVIEW [11/08/2018 07:59:16]

56

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 6. Updating the Menu: Creating a String to Name a Saved Configuration
NOTE: Delete Directory ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver
before the Build command to build the MyWizardDriver Clean

End of Lab 6

DRAFT FOR REVIEW [11/08/2018 07:59:16]

57

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 7. Updating the Menu: Numeric Entry

Lab 7. Updating the Menu: Numeric Entry
In this lab, you’ll learn how to add a numeric entry to your driver menu. This lab uses the
VFR term “

numeric

” that prompts the user to enter a free-form numeric value. The VFR

determines the minimum and maximum values with the terms “

minimum

Since there is also an enable/disable switch, the VFR uses the “

” and “

suppressif

maximum

”.

” term to display

or hide this field when disabled. Also this field displays as decimal (default) or hexadecimal
with the “

flags

” switch.

Figure 7 : Menu with Numeric item entry
1. Update the MyWizardDriver.vfr file
2. Add the following code in the location shown below at approx. Line 90 and before the
“

resetbutton

” item:

DRAFT FOR REVIEW [11/08/2018 07:59:16]

58

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 7. Updating the Menu: Numeric Entry
//
// Define a numeric free form menu item
//
suppressif

ideqval MWD_IfrNVData.MyWizardDriverChooseToEnable == 0x0;

numeric varid

= MWD_IfrNVData.MyWizardDriverHexData,

prompt

= STRING_TOKEN(STR_DATA_HEX_PROMPT),

help

= STRING_TOKEN(STR_NUMERIC_HELP),

flags

= DISPLAY_UINT_HEX ,

// Display in HEX format (if not specifie

d, default is in decimal format)
minimum = 0,

3. Save MyWizardDriver.vfr
4. Update the MyWizardDriver.uni file
5. Add the following code to the bottom of the file:
#string STR_DATA_HEX_PROMPT

#language en "Enter ZY Base (Hex)"

#string STR_NUMERIC_HELP

#language en "This is the help for entering a B

ase address in Hex. The valid range in this case is from 0 to 250."

6). Save MyWizardDriver.uni

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

DRAFT FOR REVIEW [11/08/2018 07:59:16]

59

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 7. Updating the Menu: Numeric Entry
2. Copy the
naming it

BIOS image created from the

OVMF.fd

build

to the run-ovmf directory

bios.bin

bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type exit

5. Now at the setup front page menu, select “Device Manager”
6. Inside the Device Manager menu press the down arrow to “My Wizard Driver Sample
Formset” Press "Enter"
Notice the value for “Enter ZY Base(Hex)” is
VFR field “

default = 0x22

022

. Hex is the default because of the

”

7. Select “Enter ZY Base(Hex)” and then Press “Enter”
8. Test by typing a “

M

” character

Notice that only Numeric characters are allowed and also only values

00

to

0FA

Hex.

When values outside the range or non-numeric characters are entered the red “!!” sting
is displayed at the bottom of the menu.
The string “!!” is part of the Browser engine :

DRAFT FOR REVIEW [11/08/2018 07:59:16]

60

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 7. Updating the Menu: Numeric Entry
MdeModulePkg\Universal\SetupBrowserDxe\SetupBrowserStr.uni
#string INPUT_ERROR_MESSAGE #language en-US "!!"

9. Press “Enter” again
10. Test by typing a value of ‘

99

’ Hex and then Press “Enter”

Notice that the “Configuration changed” message is displayed.
11. Test the “

surpressif

” by pressing the “spacebar” to “Enable My XYZ Device” then

press the “Space” bar to toggle off or “Disabled”.
Notice the “Select Base Address” and “Name of Configuration” fields are now grayed
out and not selectable and the “Enter ZY Base(Hex)” does not appear at all.

DRAFT FOR REVIEW [11/08/2018 07:59:16]

61

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 7. Updating the Menu: Numeric Entry
12. Press “Space bar” again to “Enable My XYZ Device” and the“Enter ZY Base(Hex)” is
displayed again

13. Press “F10” to save, then “Escape” to exit
14. Press “Escape” to exit the “Device Manager”
15. Select “Continue” and then Press "Enter”
16. At the Shell Prompt, type
Notice by
named

dmpstore –all

modifyingMyWizardDriverNVDataStruc.h

MWD_IfrNVData

of type

our data structure stored in NVRAM is

MYWIZARDDRIVER_CONFIGURATION

.

17. Type “reset” at the Shell prompt

18. Exit QEMU

For any build issues copy the solution files from ~/FW/LabSolutions/LessonE.7
NOTE: Delete Directory ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver
before the Build command to build the MyWizardDriver Clean

DRAFT FOR REVIEW [11/08/2018 07:59:16]

62

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 7. Updating the Menu: Numeric Entry

End of Lab 7

DRAFT FOR REVIEW [11/08/2018 07:59:16]

63

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 8. Updating your Driver for Interactive Call Backs

Lab 8. Updating your Driver for Interactive Call
Backs
In this lab, you’ll update your driver for interactive call backs. Call backs are a way to
communicate changes the user is making in “real time” where your driver needs to intervene
as the changes are made and before the user exits the current menu being displayed. These
would be exception cases that the driver could interrupt the normal browser engine process.
To add call backs, the file

HiiConfigAccess.c

MyWizardDriverHiiConfigAccessCallback

have a flag for

INTERACTIVE

of your driver will be updated in the function

. This function is called whenever any VFR items

set. So far, the previous labs did not have any call back items.

We can see this because there was a “Debug” call made in the
MyWizardDriverHiiConfigAccessCallback
HiiConfigAccess.c

function that never gets called:

(line 331)

DEBUG ((DEBUG_INFO, "\n:: START Call back ,Question ID=0x%08x Type=0x%04x Action=0x%04
x", QuestionId, Type, Action));

Lab 8a. Add the Case statements to the Call back routine
1. Update the HiiConfigAccess.c file
2. Add the following code before

return status

; to include a “

case

” statement in the call

back routine for the “action” passed. | Add the following code at approx. line 343 before:
return status;

DRAFT FOR REVIEW [11/08/2018 07:59:16]

64

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 8. Updating your Driver for Interactive Call Backs
//Begin Code
switch (Action) { // Start switch and passed param Action
case EFI_BROWSER_ACTION_FORM_OPEN:

// 3

{
}
break;
case EFI_BROWSER_ACTION_FORM_CLOSE: // 4
{
}
break;
case EFI_BROWSER_ACTION_RETRIEVE: // 2
{
}
break;
//End Code

DRAFT FOR REVIEW [11/08/2018 07:59:16]

65

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 8. Updating your Driver for Interactive Call Backs

3. Save HiiConfigAccess.c

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

DRAFT FOR REVIEW [11/08/2018 07:59:16]

66

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 8. Updating your Driver for Interactive Call Backs
2. Copy the
naming it

OVMF.fd

BIOS image created from the

build

to the run-ovmf directory

bios.bin

bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type exit
5. Now at the setup front page menu, select “Device Manager”
6. Inside the Device Manager menu press the down arrow to “My Wizard Driver Sample
Formset” Press "Enter"
7. Notice that there are No Debug messages for Call back to the QEMU Console.
8. Press “Escape” and another "Escape" to exit the “Device Manager”
9. Select “Continue” and then Press "Enter”
10. Type “reset” at the Shell prompt

11. Exit QEMU

Lab 8b. Update the Menu for Interactive items
1. Update the MyWizardDriver.vfr file
2. Now, you’ll add the flag characteristic
keyword

INTERACTIVE

and

questionid

INTERACTIVE

to the string item’s flags by using

. Add the following code in the location shown

below:
Approx. line 83 and line 86
questionid = 0x1001,
flags = INTERACTIVE,

DRAFT FOR REVIEW [11/08/2018 07:59:16]

67

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 8. Updating your Driver for Interactive Call Backs
3. Include the numeric item by adding the following code in the location shown below,
Approx. line 97 and line 100
questionid = 0x1111,
| INTERACTIVE ,

4. Save MyWizardDriver.vfr

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

2. Copy the
naming it

OVMF.fd

BIOS image created from the

build

to the run-ovmf directory

bios.bin

bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type exit
5. Now at the setup front page menu, select “Device Manager”
6. Inside the Device Manager menu press the down arrow to “My Wizard Driver Sample
Formset” Press "Enter"
7. Take a moment and review the QEMU Console window
8. In the emulation window, click on “Name of Configuration” and “Enter ZY Base(Hex)”
9. Notice the following in the QEMU Console window:
Every time the browser does anything with the interactive labeled fields there is a call
made to your driver’s call back function. We can determine which item by the
quetionid

and what action by the Action passed to your call back function. Your call

DRAFT FOR REVIEW [11/08/2018 07:59:16]

68

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 8. Updating your Driver for Interactive Call Backs
back function can then add code to special case when these transitions occur.
Entering Form

Changing a Value for Question ID 0x1111

Changing a Value for Question ID 0x1001

10. Press “Escape” and another "Escape" to exit the “Device Manager”
11. Select “Continue” and then Press "Enter”
12. Type “reset” at the Shell prompt

13. Exit QEMU

DRAFT FOR REVIEW [11/08/2018 07:59:16]

69

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 8. Updating your Driver for Interactive Call Backs
For any build issues copy the solution files from ~/FW/LabSolutions/LessonE.8
NOTE: Delete Directory ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver
before the Build command to build the MyWizardDriver Clean

End of Lab 8

DRAFT FOR REVIEW [11/08/2018 07:59:16]

70

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 9. Add code to your driver when Call Back events occur for Interactive Items

Lab 9. Add code to your driver when Call Back
events occur for Interactive Items
In this lab, you’ll update your driver to print debug statements when the HII browser engine
calls back into your call back function. Every time the browser does anything with the
interactive labeled fields there is a call made to your driver’s call back function. We can
determine the item by the

quetionid

and what action based on the action passed to your

call back function. Your call back function can then add code to special case when these
transitions occur.
For this lab we will simply add Debug print statements. However, the use of adding call
backs to a driver’s HII functions adds the capability of providing more manageability and
flexibility for the interactions between the user, the browser engine, and your driver code. In
a real driver firmware situation, it may be desired to implement more complex features and
functionality based upon an item changing.
1. Update the HiiConfigAccess.c file
2. Comment out the DEBUG statement with “
MyWizardDriverHiiConfigAccessCallback

//

” in the

call back function approx. line 330:

//

3. Add a switch case statement of the question ID’s to the “Action” switch case of
EFI_BROWSER_ACTION_CHANGING

in the call back function by adding a nested switch case

code (as shown below at approx. line 372 )

DRAFT FOR REVIEW [11/08/2018 07:59:16]

71

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 9. Add code to your driver when Call Back events occur for Interactive Items
switch (QuestionId) {
case 0x1111:
DEBUG ((DEBUG_INFO, "\n:: START Call back- Changing ,Question ID
=0x%08x Type=0x%04x Action=0x%04x", QuestionId, Type, Action));
break;
case 0x1001:
DEBUG ((DEBUG_INFO, "\n:: START Call back- Changing ,Question ID
=0x%08x Type=0x%04x Action=0x%04x", QuestionId, Type, Action));
break;
default:
Status = EFI_UNSUPPORTED;
break;
}

4. Add another nested switch case statement of the question ID’s to the “Action” switch
case of EFI_BROWSER_ACTION_CHANGED in the call back function (as show below
at approx. line 388):
switch (QuestionId) {
case 0x1111:
DEBUG ((DEBUG_INFO, "\n:: START Call back- Changed ,Question ID=0
x%08x Type=0x%04x Action=0x%04x", QuestionId, Type, Action));
break;
case 0x1001:
DEBUG ((DEBUG_INFO, "\n:: START Call back- Changed ,Question ID=0
x%08x Type=0x%04x Action=0x%04x", QuestionId, Type, Action));
break;
default:
Status = EFI_UNSUPPORTED;
break;
}

DRAFT FOR REVIEW [11/08/2018 07:59:16]

72

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 9. Add code to your driver when Call Back events occur for Interactive Items

1. Save MyWizardDriver.c

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

2. Copy the
naming it

OVMF.fd

BIOS image created from the

build

to the run-ovmf directory

bios.bin

bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type exit
5. Now at the setup front page menu, select “Device Manager”
6. Inside the Device Manager menu press the down arrow to “My Wizard Driver Sample
Formset” Press "Enter"
7. Observe the QEMU Console Window or debug output
Test: in the your drivers menu by changing the “Name of Configuration” and the “Enter
ZY Base(Hex)” fields while observing the QEMU Console Window or debug output.
8. Observe in the QEMU Console Window or debug output the changes that you made.

DRAFT FOR REVIEW [11/08/2018 07:59:16]

73

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 9. Add code to your driver when Call Back events occur for Interactive Items

Notice: when changing the “Name of Configuration” field

Notice: when changing the “Enter ZY Base(Hex)” field

Notice: when Pressing “F10”
9. Press “Escape” and another "Escape" to exit the “Device Manager”
10. Select “Continue” and then Press "Enter”
11. Type “reset” at the Shell prompt

12. Exit QEMU

For any build issues copy the solution files from ~/FW/LabSolutions/LessonE.9
NOTE: Delete Directory ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver
before the Build command to build the MyWizardDriver Clean

End of Lab 9

DRAFT FOR REVIEW [11/08/2018 07:59:16]

74

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 10. Adding an Additional Form Page

Lab 10. Adding an Additional Form Page
In this lab, you’ll learn how to add another form page to your My Wizard Driver menu by
using the “

goto

” VFR term along with the “

Additionally, use “

surpressif

” or “

form

grayoutif

” and “

formid

” VFR statements.

” to conditionally allow the user to enter your

additional forms.
In addition, this lab will show how the “time” and “date” VFR terms are used within the VFR
language to special case how the browser engine checks the time instead of your driver
manually checking (e.g. leap year).

Figure 10: Second setup page
1. Update the MyWizardDriverNVDataStruc.h file
2. Add the following date and time fields to the configuration

typedef

(to to the location

shown below):
EFI_HII_TIME

Time;

EFI_HII_DATE

Date;

DRAFT FOR REVIEW [11/08/2018 07:59:16]

75

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 10. Adding an Additional Form Page

3. Save MyWizardDriverNVDataStruc.h
4. Update the MyWizardDriver.uni file
5. Add the following code to the end of the file to update the second page’s string:
#string STR_FORM2_TITLE

#language en "MyWizardDriver Second Setup Page"

#string STR_DATE_PROMPT

#language en "System Date"

#string STR_DATE_HELP

#language en "This is the help for the Date (mo

nth/day/year). (Error checking will be done against month/day/year combinations that a
re not supported.)"
#string STR_TIME_PROMPT

#language en "System Time"

#string STR_TIME_HELP

#language en "This is the help for the Time (ho

ur/minute/second)."
#string STR_ERROR_POPUP

#language en "You typed in the wrong value!"

#string STR_GOTO_FORM1

#language en "Enter Page 1"

#string STR_GOTO_FORM2

#language en "Enter Page 2"

#string STR_GOTO_HELP

#language en "This is my goto help"

#string STR_MY_DATE_PROMPT

#language en "My System Date"

#string STR_MY_TIME_PROMPT

#language en "My System Time"

6). Save MyWizardDriver.uni
7). Update the MyWizardDriver.vfr file
8). Add the “

goto

” VFR item to allow browser to ender another form by adding the

following code before the "
grayoutif

endform

” at approx. line 114

ideqval MWD_IfrNVData.MyWizardDriverChooseToEnable == 0x0;

goto 2,
prompt = STRING_TOKEN(STR_GOTO_FORM2), //SecondSetupPage
help

= STRING_TOKEN(STR_GOTO_HELP);

endif;

DRAFT FOR REVIEW [11/08/2018 07:59:16]

76

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 10. Adding an Additional Form Page

9). Add the following code between “

endform

” at approx. line 120 and “

endformset

” (the

code continues for few pages in this lab guide):
// Begin code
form formid = 2,

// SecondSetupPage,

title = STRING_TOKEN(STR_FORM2_TITLE);
grayoutif TRUE; // DATE is the date of the Windows Host so can not change it.;
date

year varid

= Date.Year, // Note that it is a member of NULL,

//so the RTC will be the system resource to retrieve and save from
prompt

= STRING_TOKEN(STR_DATE_PROMPT),

help

= STRING_TOKEN(STR_DATE_HELP),

minimum

= 1998,

maximum

= 2099,

step

= 1,

default

= 2010,

month varid = Date.Month, // Note that it is a member of NULL,
//so the RTC will be the system resource to retrieve and save from
prompt

= STRING_TOKEN(STR_DATE_PROMPT),

help

= STRING_TOKEN(STR_DATE_HELP),

minimum

= 1,

maximum

= 12,

step

= 1,

default

= 1,

day varid

= Date.Day, // Note that it is a member of NULL,

//so the RTC will be the system resource to retrieve and save from
prompt

= STRING_TOKEN(STR_DATE_PROMPT),

help

= STRING_TOKEN(STR_DATE_HELP),

minimum

= 1,

maximum

= 31,

step

= 0x1,

default

= 1,

enddate;
endif;

//grayoutif TRUE DATE

grayoutif TRUE;
time

// TIME – WINDOWS TIME

hour varid

= Time.Hour, // Note that it is a member of NULL,

DRAFT FOR REVIEW [11/08/2018 07:59:16]

77

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 10. Adding an Additional Form Page
//so the RTC will be the system resource to retrieve and save from
prompt

= STRING_TOKEN(STR_TIME_PROMPT),

help

= STRING_TOKEN(STR_TIME_HELP),

minimum

= 0,

maximum

= 23,

step

= 1,

default

= 0,

minute varid

= Time.Minute, // Note that it is a member of NULL,

//so the RTC will be the system resource to retrieve and save from
prompt

= STRING_TOKEN(STR_TIME_PROMPT),

help

= STRING_TOKEN(STR_TIME_HELP),

minimum

= 0,

maximum

= 59,

step

= 1,

default

= 0,

second varid

= Time.Second, // Note that it is a member of NULL,

//so the RTC will be the system resource to retrieve and save from
prompt

= STRING_TOKEN(STR_TIME_PROMPT),

help

= STRING_TOKEN(STR_TIME_HELP),

minimum

= 0,

maximum

= 59,

step

= 1,

default

= 0,

endtime;
endif; //grayoutif TRUE

TIME

date // My Wizard Driver Date
varid = MWD_IfrNVData.Date ,
prompt = STRING_TOKEN(STR_MY_DATE_PROMPT),
help = STRING_TOKEN(STR_DATE_HELP),
flags = STORAGE_NORMAL,
default = 2013/01/01,
enddate;
time // My Wizard Driver Time
name

= MyTimeMWD,

varid

= MWD_IfrNVData.Time,

prompt

= STRING_TOKEN(STR_MY_TIME_PROMPT),

help

= STRING_TOKEN(STR_TIME_HELP),

flags

= STORAGE_NORMAL ,

default = 15:33:33,
endtime;
goto 1,
prompt = STRING_TOKEN(STR_GOTO_FORM1), //MainSetupPage
// this too has no end-op and basically it's a jump to a form ONLY
help

= STRING_TOKEN(STR_GOTO_HELP);

endform;

DRAFT FOR REVIEW [11/08/2018 07:59:16]

78

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 10. Adding an Additional Form Page
// End code

10). Save MyWizardDriver.vfr

Build and test MyWizardDriver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

2. Copy the
naming it

OVMF.fd

BIOS image created from the

build

to the run-ovmf directory

bios.bin

bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type exit
5. Now at the setup front page menu, select “Device Manager”
6. Inside the Device Manager menu press the down arrow to “My Wizard Driver Sample
Formset” Press "Enter"

DRAFT FOR REVIEW [11/08/2018 07:59:16]

79

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 10. Adding an Additional Form Page

Notice the “Enter Page 2” option. Without

goto

in the

MyWizardDriver.vfr

file, you

wouldn’t be able to access page two.
7. Select “Enter Page 2” and then Press “Enter”
Notice how the System Date and Time cannot be modified to any other date/time and is
grayed out:

DRAFT FOR REVIEW [11/08/2018 07:59:16]

80

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 10. Adding an Additional Form Page
8. Test by trying to enter the date 02/30/2013, then try a valid leap year date: 02/29/2012.
9. Press “Down Arrow” to return to Page 1
10. Test the “

grayoutif”

by going to “Enable My XYZ Device”

11. Press the “Spacebar” to toggle off/disable
Notice the “Select Base Address” , “Name of Configuration” and the “Enter Page 2”
fields are now grayed out and not selectable

12. Press “Space bar” again to Enable
13. Press “F10” then “Escape” to save and exit
14. Press “Escape” to exit “Device Manager”
15. Select “Continue” and then Press "Enter”
16. Type “reset” at the Shell prompt

17. Exit QEMU

For any build issues copy the solution files from ~/FW//LabSolutions/LessonE.10
NOTE: Delete Directory ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver
before the Build command to build the MyWizardDriver Clean

End of Lab 10

DRAFT FOR REVIEW [11/08/2018 07:59:16]

81

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 11. Adding Communication from Driver to Console through HII

Lab 11. Adding Communication from Driver to
Console through HII
In this lab, you’ll add communication from the driver to the console through HII. More
specifically, you’ll add code to retrieve a string from the HII database and print the string to
the console. Then, you’ll add the string in French, change the language, and test to ensure
the correct language is displayed. The reason the driver should avoid direct string text to the
console without the HII support is because there is no localization for text string inside the
driver’s source code. By using the HII database the strings are tokenized making localization
easier.

Examine the MdeModulePkg.Chm for HII
1. Use the .Chm reader and open the MdeModulePkg.Chm. For HII database library
functions are in the MdeModulePkg .Chm file. Search on HiiLib.h functions
2. Select the Index tab
3. Type: HiiLib.h

Note: Notice the list of Hii function calls available. To get Strings the

HiiGetString

function can be used.

Add changes to your Driver

DRAFT FOR REVIEW [11/08/2018 07:59:16]

82

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 11. Adding Communication from Driver to Console through HII
1. Update the ~/src/edk2/OvmfPkg/OvmfPkgX64.fdf file
2. Make your driver stand alone again. Remove (or comment out) the include statement in
the OvmfPkgX64.fdf file:
#INF MyWizardDriver/MyWizardDriver.inf

3. Save OvmfPkgX64.fdf
4. Update the MyWizardDriver.uni file
5. Add the following code to the top of the file at approx. line 14 as shown:
#langdef fr-FR "Francais"

6. Add the following code to the end of the file:
#string STR_LANGUAGE_TEST_STRING

#language en "Laurie's Test String"
#language fr-FR "Chaîne de test de Laurie"

7). Save MyWizardDriver.uni
8). Update the MyWizardDriver.c file
9). Add the following local variable for
“

Status = EFI_SUCCESS;

StringPtr

after “

BOOLEAN ActionFlag;

” and before

”(as shown below):

EFI_STRING StringPtr;

10). Add the following code after “

FreePool (ConfigRequestHdr);

” (as shown below) to edit

the driver’s entry point with a debug and print statement by making a call to the
HiiGetString

for the token to print (at approx line 364):

DRAFT FOR REVIEW [11/08/2018 07:59:16]

83

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 11. Adding Communication from Driver to Console through HII
StringPtr

= HiiGetString (HiiHandle[0], STRING_TOKEN (STR_LANGUAGE_TEST_STRING)

, NULL);
DEBUG ((EFI_D_INFO,"[MyWizardDriver-Entrypoint] My String was: %s\n", StringPtr) );
Print(L"%s\n", StringPtr );

11). Save the MyWizardDriver.c

Build and test Driver
1. At the Terminal Command Prompt (Cntl-Alt-T)
bash$ cd ~/src/edk2
bash$ build

2. Copy the
naming it

OVMF.fd

BIOS image created from the

build

to the run-ovmf directory

bios.bin

bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

3. Invoke Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh

4. At the UEFI Shell prompt,type fs0:
5. Type Load MyWizardDriver.efi and then Press “Enter”

Notice that the string’s English version is displayed:
6. Type Reset and then Press “Enter”
7. Type "build run" and then Press “Enter”
8. Type "exit" at the shell prompt

DRAFT FOR REVIEW [11/08/2018 07:59:16]

84

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 11. Adding Communication from Driver to Console through HII
9. Select Language and then Press “Enter”

10. Select “Français” and then Press “Enter”

11. Select “Continuer” and then Press “Enter”

12. At the Shell Prompt, type Fs0:
13. Type load MyWizardDriver.efi

14. Type “reset” and then Press “Enter”

15. Exit QEMU

For any build issues copy the solution files from ~/FW/LabSolutions/LessonE.11 NOTE:
Delete Directory

DRAFT FOR REVIEW [11/08/2018 07:59:16]

85

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab 11. Adding Communication from Driver to Console through HII
~/src/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MyWizardDriver before the Build command
to build the MyWizardDriver Clean. Make sure you update OvmfPkgX64.fdf.

End Lab 11

DRAFT FOR REVIEW [11/08/2018 07:59:16]

86

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab Setup

LAB SETUP LINUX FOR UBUNTU 16.04
1. Download the UEFI Training Materials .zip (accept any security notifications)
2. Click “Open” and Extract the file to HOME which will take a few minutes
Note: It is highly important that you unzip the file correctly to this location because all
the file locations in this training guide follow that format. The Default will be in

/FW/...

Directory
~/Lab_Material_FW/FW

Documentation
DriverWizard
edk2
edk2Linux
LabSampleCode
3. Install the Ubuntu Linux tools:
bash$ sudo apt-get install build-essential uuid-dev iasl git
bash$ sudo apt-get install gcc-5 nasm
bash$ sudo apt-get install qemu

4. Create a directory “src”
bash$ mkdir ~src

5. From the

~.../FW

folder, copy and paste folder “

6. Rename or mv the directory “

~.../FW/edk2

~src/edk2/BaseTools

” to

~src

” to something else

bash$ cd ~src/edk2
bash$ mv BaseTools BaseToolsX

7. Extract the file

~FW/edk2Linux/BaseTools.tar.gz

to

~src/edk2

bash$ cd ~src/edk2

8. Make the BaseTools and setup the environment
bash$ make –C BaseTools
bash$ . edksetup.sh

9. Open the file Conf/target.txt
bash$ gedit Conf/target.txt

10. Update the following:
ACTIVE_PLATFORM

= OvmfPkg/OvmfPkgX64.dsc

TARGET_ARCH

= X64

TOOL_CHAIN_TAG

= GCC5

DRAFT FOR REVIEW [11/08/2018 07:59:16]

87

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab Setup

1. Save and Exit target.txt
2. To build OvmfPkg Type
bash$ build

3. The file OVMF.fd should be in the Build directory:
~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd

Build errors
For build errors the Build option for GCC5 may need to be updated:
1. Edit ~/src/edk2/tools_def.txt
2. Find

DEFINE GCC44_ALL_CC_FLAGS

remove the "

-Werror

" flag because it will treat

warnings as errors.
DEFINE GCC44_ALL_CC_FLAGS = -g -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall
-Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -fno-common DSTRING_ARRAY_NAME=$(BASE_NAME)Strings

3. Save tools_def.txt
4. Build again Type
bash$ build

Invoke QEMU to run UEFI Shell
1. Create a run-ovmf directory under the home directory
bash$ cd ~
bash$ mkdir ~run-ovmf
bash$ cd run-ovmf

2. Create a directory hda-contents to use as a hard disk image
bash$ mkdir hda-contents

3. Copy the
naming it

OVMF.fd

BIOS image created from the

build

to the run-ovmf directory

bios.bin

DRAFT FOR REVIEW [11/08/2018 07:59:16]

88

UEFI Driver HII Linux Lab Guide[DRAFT]
Lab Setup
bash$ cp ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd bios.bin

4. Create a Linux shell script to run the QEMU from the run-ovmf directory
bash$ gedit RunQemu.sh

Add the following:
qemu-system-x86_64 -pflash bios.bin -hda fat:rw:hda-contents -net none -debugcon file:
debug.log -global isa-debugcon.iobase=0x402

1. Save RunQemu.sh and exit
2. Run the RunQemu.sh Linux Shell Script:
bash$ . RunQemu.sh

End of Lab Setup for Linux

DRAFT FOR REVIEW [11/08/2018 07:59:16]

89

UEFI Driver HII Linux Lab Guide[DRAFT]
Reference

REFERENCE

Glossary of UEFI Terms and Acronyms
https://github.com/tianocore/tianocore.github.io/wiki/Acronyms-and-Glossary

DRAFT FOR REVIEW [11/08/2018 07:59:16]

90

UEFI Driver HII Linux Lab Guide[DRAFT]
Reference

Helpful Links
UEFI Forum

http://www.uefi.org

UEFI Open Source

http://www.tianocore.org

EFI Developer Kit
(EDK II)

http://tianocore.github.io/edk2.html

EDK II Documents

http://www.tianocore.org/docs/

UEFI Shell
Documents

https://github.com/tianocore/tianocore.github.io/wiki/ShellPkg

DRAFT FOR REVIEW [11/08/2018 07:59:16]

91



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.4
Linearized                      : No
Author                          : laurie0131
Create Date                     : 2018:11:08 19:59:22+00:00
Producer                        : calibre 2.57.1 [http://calibre-ebook.com]
Title                           : UEFI_Driver_HII_Linux_Lab_Guide
Description                     : Lab and Reference Guide for Porting UEFI Driver to include HII, Assumes Linux Ubuntu 16.04
Creator                         : laurie0131
Publisher                       : GitBook
Subject                         : 
Language                        : en
Metadata Date                   : 2018:11:08 19:59:22.780245+00:00
Timestamp                       : 2018:11:08 19:59:19.174674+00:00
Page Count                      : 91
EXIF Metadata provided by EXIF.tools

Navigation menu