---?image=assets/images/gitpitch-audience.jpg
@title[Writing_UEFI_App_WIN_Lab]
with Windows Labs
tianocore.org
See also LabGuide.md for Copy&Paste examples in labs
Note: PITCHME.md for UEFI / EDK II Training How to Write a UEFI Application Lab
Copyright (c) 2020, Intel Corporation. All rights reserved.
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:
-
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.
-
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 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.
@title[Lesson Objective]
- @fa[certificate gp-bullet-green] UEFI Application with PCDs
- @fa[certificate gp-bullet-cyan] Simple UEFI Application
- @fa[certificate gp-bullet-yellow] Add functionality to UEFI Application
- @fa[certificate gp-bullet-magenta] Using EADK with UEFI Application
---?image=assets/images/binary-strings-black2.jpg
@title[UEFI Application w/ PCDs Section]
---?image=/assets/images/slides/Slide4.JPG
@title[EDK II PCD’s Purpose and Goals]
EDK II PCD’s Purpose and Goals
@fa[github gp-bullet-gold] Documentaton : MdeModulePkg/Universal/PCD/Dxe/Pcd.inf- Establishes platform common definitions
- Build-time/Run-time aspects
- Binary Editing Capabilities
- Simplify porting
- Easy to associate with a module or platform
Note:
- Standardize exposure of platform & module settings
- Help with Platform Porting
- Component information is collected from PCD definitions that are associated with a given module
- APIs are provided which allow access to component settings during the operation of the platform
- A module can carry its own PCD data in the binary image and have it exposed so the data can be edited in the flash image
---?image=/assets/images/slides/Slide4.JPG @title[PCD Syntax review]
PCDs can be located anywhere within the Workspace even though a different package will use those PCDs for a given project
@snap[west span-30 ]
@color[yellow](.DEC)
@box[bg-gold2 text-black waved ](DefinePCD)
@snapend
@snap[midpoint span-30 ]
@color[yellow](.INF)
@box[bg-green-pp text-black waved ](Reference PCD)@snapend
@snap[east span-30 ]
@color[yellow](.DSC)
@box[bg-lt-blue-pp text-black waved ](ModifyPCD)
@snapend
@snap[west span-100 fragment]
Package Module Platform
Note:
-
The Platform configuration database is generated by the build process parsing the build description files that define and specify PCD entries.
-
What we see on this slide is how the PCD data is being used in various levels of the build description files
-
First we have the DEC file – this Defines a list of PCD tokens that modules can use. It Defines the PCD entries that will exist under the GUID for that package, the PCD restriction, valid types for the PCD, and a default value for the PCD. There is a whole syntax and how to define a PCD in the DEC file.
-
Next we have PCB entries in the INF file- and this Defines the usage of PCD tokens by the module. It Defines what PCD entries are being used within the module, the PCD restriction (or DYNAMIC for none), and a Optional default value for the PCD within this module only.
-
Next is the DSC file – This is at the Platform level and describes the contents of the build for a specific platform. PCD entries are assigned values and types for the platform build. You would define a value here to be used by that platform. The value could be different when it is defined in the DEC file but the value in the DSC would be the final value . And They Cannot conflict with established restrictions.
-
Not on this slide but also there is the FDF build description File – and this file would have flash layout related values
-
Defines list of PCD tokens that modules can use.
-
Defines the PCD entries that will exist under the GUID for that package, the PDC restriction, valid types for the PCD, and a default value for the PCD.
-
The DEC file is part of a package. Any package may define PCD entries. Any module that depends on a package may use the PCD entries defined in that packages' DEC file
-
Defines usage of PCD tokens by the module
-
Defines what PCD entries are being used within the module, the PCD restriction (or DYNAMIC for none), and a default value for the PCD within this module only.
-
The INF file also carries descriptive text for a given PCD entry
- Platform level file which describes the contents of the build for a specific platform.
- PCD entries are assigned values and types for the platform build. Cannot conflict with established restrictions.
- In most cases, PCD entries do not have SKU enabled and have a single value associated with them. However, a SKU PCD entry may have multiple values.
---?image=/assets/images/slides/Slide_LabSec.JPG
@title[Lab 1: Writing UEFI Applications with PCDs]
Lab 1: Writing UEFI Applications with PCDs
Note:
---?image=/assets/images/slides/Slide7_1.JPG @title[EDK II HelloWorld App Lab ]
EDK II HelloWorld App Lab
First Setup for Building EDK II, See Lab Setup for EmulatorPkgLocate and Open
MdeModulePkg/Application/HelloWorld/HelloWorld.c
Build EmulatorPkg Emulation
Then Run HelloWorld at the Shell command interface
-
So the steps for getting the source code, hopefully everyone did this prior to this training because it does take some time to download.
-
So here are the steps:
-
First create a directory, and for our example case we are using the directory "~src/Fw"
-
Use instructions on wiki here: https://github.com/tianocore/tianocore.github.io/wiki/UDK2018-How-to-Build or use the lab material edk2
@title[EDK II HelloWorld App Lab steps]
EDK II HelloWorld App Lab
Open a VS Command Prompt and type: cd C:\FW\edk2 then ```shell C:/FW/edk2-ws> Setenv.bat C:/FW/edk2-ws> cd edk2 C:/FW/edk2-ws/ed2> edksetup ``` Build the EmulatorPkg Emulation ```shell C:/FW/edk2-ws/edk2> Build –D ADD_SHELL_STRING C:/FW/edk2-ws/edk2> RunEmulator.bat ``` At the UEFI Shell prompt ```shell Shell> Helloworld UEFI Hello World! Shell> ```How can we force the HelloWorld application to print out 3 times ?
Note: RunEmulator.bat will run WinHost.exe from Build/EmulatorX64/DEBUG_TAG/X64
Note:
Same as slide
---?image=/assets/images/slides/Slide9.JPG @title[EDK II HelloWorld App Lab location]
EDK II HelloWorld App Lab
@fa[github gp-bullet-gold] MdeModulePkg/Application/HelloWorld
Note:
First let's look at the source code for the HellowWorld Application
@title[EDK II HelloWorld App Lab code]
EDK II HelloWorld App Lab
Source: Helloworld.c ```C EFI_STATUS EFIAPI UefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { UINT32 Index; Index = 0; // Three PCD type (FeatureFlag, UINT32 // and String) are used as the sample. if (FeaturePcdGet (PcdHelloWorldPrintEnable)) { for (Index = 0; Index < PcdGet32 (PcdHelloWorldPrintTimes); Index ++) { // Use UefiLib Print API to print
// string to UEFI console
Print ((CHAR16*)PcdGetPtr (PcdHelloWorldPrintString));
}
}
return EFI_SUCCESS; }
@[12](PCD that is a boolean for if this feature is enabled)
@[13](PCD that is an integer <font face="Consolas">For</font> loop for how many times to print to the the string)
@[18](PCD that is a pointer for the string to print out)
Note:
Source from Helloworld.c
---?image=/assets/images/slides/Slide11.JPG
@title[EDK II HelloWorld App Lab solution]
<p align="right"><span class="gold" ><b>EDK II HelloWorld App Solution </b></span></p>
<p style="line-height:60%" align="left" ><span style="font-size:0.7em;" >1. Edit the file <font face="Consolas">C:/FW/edk2-ws/edk2/EmulatorPkg/EmulatorPkg.dsc</font><br><br>
After the section <font face="Consolas">[PcdsFixedAtBuild] </font> (search for "<font face="Consolas">PcdsFixedAtBuild</font>" or "Hello")
<br>
<br>
<br>
<br>
</span></p>
<p style="line-height:45%" align="left" ><span style="font-size:0.52em; font-family:Consolas;" ><font color="black"><br>
[PcdsFixedAtBuild]<br>
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintTimes|3
</font>
</span></p>
<p style="line-height:60%" align="left" ><span style="font-size:0.7em;" ><br><br>2.
Re-Build – Cd to <font face="Consolas">C:/FW/edk2-ws/edk2</font>
</span></p>
```shell
$> Build –D ADD_SHELL_STRING
Note:
-
look in file: C:\fw\edk2\MdeModulePkg\MdeModulePkg.Dec
-
This PCD defines the print string.
-
This PCD is a sample to explain String typed PCD usage.
-
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString|L"UEFI Hello World!\n"|VOID*|0x40000004
- Edit the file EmulatorPkg/EmulatorPkg.dsc
- After the section [PcdsFixedAtBuild], add the new line :
[PcdsFixedAtBuild]
gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintTimes|3
- Re-Build – Cd to FW/edk2 dir
bash$ build -D ADD_SHELL_STRING
- RunEmulator.bat
@title[EDK II HelloWorld App Lab solution 02]
EDK II HelloWorld App Solution
3. Run Emulation (run WinHost.exe from Build/EmulatorX64/ . . ./X64 )
```shell C:/FW/edk2-ws/edk2> RunEmulator.bat ```4. At the Shell prompt
```shell Shell> Helloworld UEFI Hello World! UEFI Hello World! UEFI Hello World! Shell>
<p style="line-height:60%" align="left" ><span style="font-size:0.7em;" >5.
Exit Emulation
</span></p>
```shell
Shell> Reset
@color[#A8ff60](How can we change the string of the HelloWorld application?)
@size[.8em]( Also see ../edk2/MdeModulePkg/MdeModulePkg.Dec)
Note: 3. RunEmulator
- At the Shell prompt
Shell> Helloworld
UEFI Hello World!
UEFI Hello World!
UEFI Hello World!
Shell>
- Exit with Reset at the shell
- How can we change the string of the HelloWorld application?
- Also see .../edk2/MdeModulePkg/MdeModulePkg.Dec
---?image=/assets/images/slides/Slide_LabSec.JPG
@title[Lab 2: Write a Simple UEFI Application]
Lab 2: Write a Simple UEFI Application
Note:
@title[Lab 2 - Write A Simple App]
LAB 2 - Writing a Simple UEFI Application
In this lab, you’ll learn how to write simple UEFI applications.@snap[north-west span-50 ]
"C" file
@box[bg-black text-white rounded my-box-pad2 ](
@snap[north-east span-48]
.inf file
@box[bg-black text-white rounded my-box-pad2 ](
@snap[south-west span-95 fragment ]
- What goes into the Simplest "C"
- Start with what should go into the Simplest .INF file
@snapend
@snap[north-east span-98 ]
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return EFI_SUCCESS;
}
@snap[north-east span-46 ]
[Defines]
INF_VERSION =
BASE_NAME =
FILE_GUID =
MODULE_TYPE =
VERSION_STRING =
ENTRY_POINT =
[Sources]
[Packages]
[LibraryClasses]
Note:
- Start with what should go into the Simplest .INF file
- What goes into a Simplest "C"
---?image=/assets/images/slides/Slide15.JPG @title[Lab 2: Application Lab –start with .c and .inf template]
Application Lab –start with .c and .inf template
Copy the LabSampleCode/SampleApp directory to C:/FW/edk2-ws/edk2
@snap[south-west span-100]
Edit SampleApp.inf
- Look in the INF for "XXXXXXXXXXX" sections that will need information
- Create Name & GUID, and then fill in the MODULE_TYPE
@snapend
Note:
- Copy the LabSampleCode/SampleApp directory to FW/edk2
- Edit SampleApp.inf
- Look in the INF for "XXXXXXXXXXX" sections that will need information
- Create Name & GUID, and then fill in the MODULE_TYPE
---?image=/assets/images/slides/Slide16.JPG @title[Lab 2: Sample Application INF file]
Lab 2: Sample Application INF file
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = XXXXXXXXXXXXXXX
FILE_GUID = XXXXXXXXXXXXXXX
MODULE_TYPE = XXXXXXXXXXXXXXX
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain
[Sources]
XXXXXXXXX
[Packages]
#XXXXXXXX
[LibraryClasses]
#XXXXXXXXXXXXX
[Guids]
# . . .
Get a GUID: guidgerator.com
@snap[north-east span-49 ]
@color[red](← ------) SampleApp
@color[red](← ------) Get a GUID guidgerator.com
@color[red](← ------) UEFI_APPLICATION
@color[red](← ------) SampleApp.c
Note:
to get a Guid - http://www.guidgenerator.com/
- Now here is a sample INF file
- This is for an application called SampleApp
- When the program starts is going to call the function called UefiMain inside the application.
- The prototype for UefiMain is predetermined and you can see an example of a prototype by downloading a sample application.
- So a couple of the things that the prototype will require are a pointer to the system table and a image handle parameter.
Add the following:
SampleApp
UEFI_APPLICATION
SampleApp.c
---?image=/assets/images/slides/Slide17.JPG @title[Lab 2: Sample Application C file]
Lab 2: Sample Application ‘C’ file
/** @file
This is a simple shell application
**/
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
@color[red](return) EFI_SUCCESS;
}
@snap[south-east span-45 ]
@color[#A8ff60](←)
@snapend
@snap[south-east span-39 ] @box[bg-navy text-white rounded my-box-pad2 ](
@color[yellow](Does not do anything but return Success)
@snapend
Note:
/** @file This is a simple shell application **/ EFI_STATUS EFIAPI UefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { return EFI_SUCCESS; }
@title[Lab 2: Will it compile now?]
Lab 2: Will it compile now?
Not yet . . .
- Need to add headers to the .C file
- Need to add a reference to INF from the platform DSC
- Need to add a few Package dependencies and libraries to the .INF
Note:
- So the question is will it compile now?
- And the answer is no it will not compile yet
- First you need to add some headers to the.C. we need to be able to let some things.
- We need to add a reference to the INF from the platform in DSC. Because If you build it now the build is going to say I don’t have a platform and so the build is going to break.
- Then the next thing we need to add is a few package dependencies and libraries to the INF file because, for instance, features like the UEFI Application entry point will need to be added, because it doesn’t know how to do an entry point until you’ve added that.
@title[Lab 2: Application Lab – Update Files]
Lab 2: Application Lab – Update Files
- 1. .DSC (EmulatorPkg/EmulatorPkg.dsc)
- [Components . . .]
- Add INF to components section, before build options
- Hint: add after comment "# Add new modules here"
@size[.8em](SampleApp/SampleApp.inf)
- 2. .INF file (SampleApp/SampleApp.inf)
- Packages (all depend on MdePkg)
- @size[.8em]([Packages] MdePkg/MdePkg.dec)
- @size[.8em]([LibraryClasses] UefiApplicationEntryPoint)
- 3. .C file - Header references File (SampleApp/SampleApp.c)
- @size[.8em](#include <Uefi.h>)
- @size[.8em](#include <Library/UefiApplicationEntryPoint.h>)
Note:
- So what are our steps for adding that
- So first we need to add the MDE package to the INF file and you need to reference the file by the DEC file so under the [packages] section you Are going to add "MdePkg/MdePkg.dec"
- Under the [LibraryClasses] section of the INF you’re going to add a reference to "UefiApplicationsEntryPoint" . And just as an interesting note is actually dependent on the "UefiBootServiecesTableLib".
- Next in the .C. file you are going to add some header references, the "Uefi.h" and "Library/UefiApplicationEntryPoint.h"
- Then in the DSC file under the "[components]" section you’re going to add a reference to your new sample INF file.
---?image=/assets/images/slides/Slide20.JPG @title[Lab 2: Lab cont. Solution ]
Lab 2: Lab cont. Solution
Note:
EmulatorPkg/EmulatorPkg.dsc in the components section of the file towards the bottom SampleApp/SampleApp.inf SampleApp/SampleApp.inf [Packages] MdePkg/MdePkg.dec [LibraryClasses] UefiApplicationEntryPoint SampleApp/SampleApp.c - near the top of the file #include <Uefi.h> #include <Library/UefiApplicationEntryPoint.h>
@title[Lab 2: Will it compile now? ]
Lab 2 : Will it compile now?
Yes, At the VS Command Prompt
C:/FW/edk2-ws/edk2> Build -D ADD_SHELL_STRING
C:/FW/edk2-ws/edk2> RunEmulator.bat
Run the application from the shell
Shell> SampleApp
Notice that the program will immediately unload because the main function is empty
Exit
Shell> Reset
Note:
-
And the answer is yes.
-
It will compile and it will even run at this point but we haven’t really added any functionality to this sample code at this point and so since the main function is empty it will unload as soon as it is called.
-
So to test it after it has build successfully you then type build run in the EDK2 directory and to run your application type in the base name that you gave it in your INF file, type that name at the shell and it will run, but it won’t do anything because there is nothing for it to do.
-
another note: The program will immediately unload because the main function is empty
---?image=/assets/images/slides/Slide22.JPG @title[Possible Build Errors ]
Possible Build Errors
Error on SampleApp.inf
The FILE_GUID was invalid or not updated from "XXX…" to a proper formatted GUID
Note: The FILE_GUID was invalid or not updated from "XXX…" to a proper formatted GUID
- left is no FILE_GUID
- right - left the "XXXX"
---?image=/assets/images/slides/Slide23.JPG @title[Possible Build Errors 02 ]
Possible Build Errors
Error on SampleApp.inf
The [Packages] was invalid or did not specify MdePkg/MdePkg.dec properly
Note:
The [Packages]
was invalid or did not specify MdePkg/MdePkg.dec properly
---?image=/assets/images/slides/Slide24.JPG @title[Possible Build Errors 03]
Possible Build Errors
Compiler Error on SampleApp.c
The #include <Library/UefiApplicationEntryPoint.h> has a typo ("Application" not "Applications")
Note:
- The
#include <Library/UefiApplicationEntryPoint.h>
has a typo ("Application" not "Applications")
---?image=/assets/images/slides/Slide25.JPG @title[Possible Build Errors 04 ]
Possible Build Errors
Compile Linker Error on unresolved reference
The SampleApp.inf section [LibraryClasses] did not reference UefiApplicationEntryPoint
Note:
The SampleApp.inf section [LibraryClasses]
did not reference UefiApplicationEntryPoint
---?image=/assets/images/slides/Slide26.JPG @title[Possible Build Errors 05]
Possible Build Errors
Error at the Shell prompt
Ensure the SampleApp.inf BaseName is SampleApp
Note: Ensure the SampleApp.inf BaseName is SampleApp
---?image=/assets/images/slides/Slide_LabSec.JPG
@title[Lab 2.1: Build Switches]
Lab 2.1: Build Switches
Note:
---?image=/assets/images/slides/Slide28.JPG @title[Lab 2.1: Build MACRO Switches ]
Build MACRO Switches
The build for EmulatorPkg is using build MACRO Switch:
@color[yellow](-D ADD_SHELL_STRING) – used to change a string in the UEFI Shell application, only used for EDK II Training (requires ShellPkg be re-built on a change of this switch)
# For UEFI / EDK II Training
# This flag is to enable a different ver string for building of the ShellPkg
# These can be changed on the command line.
DEFINE ADD_SHELL_STRING = FALSE
First delete directory Build/EmulatorX64/DEBUG_tag/X64/ShellPkg
Note:
---?image=/assets/images/slides/Slide29.JPG @title[Lab 2.1: Compiling w/out Build Switch ]
Lab 2.1: Compiling w/out Build Switch
At the VS Command Prompt, Build without the "-D" Switch@snap[north-west span-60]
@box[bg-black text-white rounded my-box-pad2 ](
@box[bg-black text-white rounded my-box-pad2 ](
@snap[north-west span-58 ]
Delete Build/EmulatorX64/DEBUG_@color[cyan](tag)/X64/@color[yellow](ShellPkg)
C:/FW/edk2-ws/edk2> Build
C:/FW/edk2-ws/edk2> RunEmulator.bat
Check the Shell version with "Ver" command
Build with the –D ADD_SHELL_STRING
Delete Build/EmulatorX64/DEBUG_@color[cyan](tag)/X64/@color[yellow](ShellPkg)
C:/FW/edk2-ws/edk2> Build -D Add_SHELL_STRING
C:/FW/edk2-ws/edk2> RunEmulator.bat
Check the Shell version with "Ver" command
@snap[south-west span-100 ]
@color[yellow](NOTE:) You may need to Delete directory: Build/EmulatorX64/DEBUG_@color[cyan](tag)/X64/@color[yellow](ShellPkg) Between each build
@snapendNote:
---?image=/assets/images/slides/Slide30.JPG @title[Lab 2.1: Compiling w/out Build Switch 02]
Lab 2.1: Compiling w/out Build Switch
Edit the file C:/FW/edk2-ws/edk2/EmulatorPkg/EmulatorPkg.dsc
@snap[north-west span-52]
@box[bg-black text-white rounded my-box-pad2 ](
@snap[north-west span-60]
Change
DEFINE ADD_SHELL_STRING = @color[yellow](TRUE)
@size[.8em]((Save the file))
@size[.8em](Delete directory: Build/ . . ./ Shellpkg)
Re-Build – Cd to /FW/edk2-ws/edk2
@size[.7em](C:/FW/edk2-ws/edk2> Build)
@size[.7em](C:/FW/edk2-ws/edk2> RunEmulator.bat)
Check the Shell version with "Ver" command
@snap[south-west span-100 ]
@color[yellow](NOTE:) You may need to Delete directory: %WORKSPACE%/Build/EmulatorX64/DEBUG_@color[cyan](tag)/X64/@color[yellow](ShellPkg) Between each build
@snapendNote:
@title[Lab 2: What we learned from LAB 2]
What we learned from LAB 2
- How to write a simple native UEFI Application
- Each module requires a .inf file with a unique GUID (use http://www.guidgenerator.com/ )
- The module created will be the base name defined in the .inf file
- The module’s .inf file is required to be included in the platform .dsc file
- The [Packages] section is required at minimum to include MdePkg/dePkg.dec
- When using a Build Switch (-D) on the command line it overrides the value in the .DSC file
Note:
@title[Lab 2: If there are Build Errors ]
Lab 2: If there are build errors …
See class files for the solution
- . . .FW/LabSampleCode/LabSolutions/LessonB.2
- Copy the .inf and .c files to C:/FW/edk2-ws/edk2/SampleApp
- Search sample DSC for reference to SampleApp.inf and add this line to your workspace DSC file
C:/FW/edk2-ws/edk2/EmulatorPkg/EmulatorPkg.dsc
@size[.8em](SampleApp/SampleApp.inf)
Invoke "build" again and check the solution
Note:
same as slide
---?image=assets/images/binary-strings-black2.jpg
@title[Add more Functionality Section]
Add Functionality to the Simple UEFI Application : Next 3 Labs
- Lab 3: Print the UEFI System Table
- Lab 4: Wait for an Event
- Lab 5: Create a Simple Typewriter function
Solutions in .../FW/LabSampleCode/LabSolutions/LessonB.n
---?image=/assets/images/slides/Slide_LabSec.JPG
@title[Lab 3: Print the UEFI System Table]
Lab 3: Print the UEFI System Table
Note:
---?image=/assets/images/slides/Slide35.JPG @title[Lab 3 : Add System Table Code]
Lab 3 : Add System Table Code
Add code to print to the console the hex address of the system table pointer
- Where is the "print" function?
- Where does the app get the pointer value? @size[.8em]((compared to mem command below))
Note:
- So let’s extend this and give it something useful to do
- so for this example we are going to have our sample application print out the system table pointer
- So how do we do that. Well remember to find a function we want we can use the help documentation or CHM file.so what we will find if we do this is that the print function is part of the UefiLib. So in order to add the print functionality we would need to add the UefiLib to our list of library classes in our INF file
- To see this example look in the files in our sample lab code SampleApp.c and SampleApp.inf
- So also as an exercise you can look at the file in the sample lab code Min.dsc, this is a platform description file without a platform or any packages that go with it, and this demonstrates the minimal contents for a DSC file that can build this application. So it will build a single application orientated toward the one we just created except nothing else. So unlike the EmulatorPkg platform description file, if you were to look at it, There are huge amounts of other components, library classes, and all of that, this Min.dsc only does the minimum requirements.
---?image=/assets/images/slides/Slide36.JPG @title[Locating the "Print" Function ]
Lab 3 : Locating the Print() Function
- 1. Search the MdePkg.chm and find that the Print function by clicking
on the "Index" tab - 2. Type "Print" and double click
- 3. Scroll to the top in the right window to see that the print function is
in the UefiLib.h file
Note:
- "MdePkg Document With Libraries.chm" located in ... Lab_Material_FW/FW/Documentation
- Search the MdePkg.chm and find that the Print function by clicking on the "Index" tab
- Type "Print" and double click
- Scroll to the top in the right window to see that the print function is in the UefiLib.h file
-
- NOTE -: Install a CHM Viewer for Ubuntu
- bash$ sudo aptitude install kchmviewer
---?image=/assets/images/slides/Slide37.JPG @title[Modifying .C & .INF Files ]
Lab 3 : Modifying .C & .INF Files
@snap[north-west span-60]
#include <Uefi.h>
#include <Library/UefiApplicationEntryPoint.h>
@color[red](#include <Library/UefiLib.h>)
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
@color[red](Print(L"System Table: 0x%p\n", SystemTable); )
return EFI_SUCCESS;
}
@snapend
@snap[north-east span-40]
[LibraryClasses]
UefiApplicationEntryPoint
@color[red](UefiLib)
@snap[south span-60]
Note: Solution files are in the lab materials directory
@snapendNote:
- SampleApp.c
#include #include #include EFI_STATUS EFIAPI UefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { Print(L"System Table: 0x%08x\n", SystemTable); return EFI_SUCCESS; } - SampleApp.inf [LibraryClasses] UefiApplicationEntryPoint UefiLib
@title[Build and Test SampleApp]
Lab 3 : Build and Test SampleApp
At the VS Command Prompt C:/FW/edk2-ws/edk2> Build
C:/FW/edk2-ws/edk2> RunEmulator.bat
Run the application from the shell
Shell> SampleApp
System Table: 0x07E34018
Shell>
Verify by using the Shell "mem" command
Exit Shell> Reset
Note:
Same as slide
End of LAB 3
---?image=/assets/images/slides/Slide_LabSec.JPG
@title[Lab 4: Waiting for an Event]
Lab 4: Waiting for an Event
Note:
---?image=/assets/images/slides/Slide40.JPG @title[Lab 4 : Add Wait for Event ]
Lab 4 : Add Wait for Event
Add code to make your application wait for a key press event (WaitForEvent / WaitForKey)
- Where are these functions located?
- What else can you do with the key press?
Note:
-
Add code to make your application wait for an event (WaitForEvent) and use the (WaitForKey) as the event
-
Hint: use the MdePkg.chm to find where the "WaitForEvent" and the "WaitForKey" functions are located
-
Another Hint: The system table is passed in as a parameter to your sample application
-
Search the EDK II code for "WaitForEvent"
-
Test by running your application in the Shell
@title[Lab 4 : How to locate functions ]
Lab 4 : HOW?
Locate Functions: WaitForEvent / WaitForKey- Search MdePkg.chm - Note: "MdePkg Document With Libraries.chm" located in ... Lab_Material_FW/FW/Documentation
- Locate WaitForEvent in Boot Services
- Locate WaitForKey and find ( EFI_SIMPLE_TEXT_INPUT_PROTOCOL will be part of ConIn )
- Check the UEFI Spec for parameters needed:
- WaitForEvent is referenced via Boot Services pointer, which is referenced via EFI System Table
- WaitForKey can be referenced through the EFI System Table passed into the application
- OR
Search the working space for WaitForEvent for an example - One can be found in MdePkg/Library/UefiLib/Console.c ~ ln 569:
Note:
- Search the MdePkg.chm and find where the "WaitForEvent" is located. It is part of the "Boot Services".
- Search the MdePkg.chm and find where the "WaitForKey" is located. It is part of the "EFI_SIMPLE_TEXT_INPUT_PROTOCOL as part of ConIn.
- The WaitForEvent can be referenced through the Boot Services pointer which can be referenced through the System Table
- The WaitForKey can be referenced through the System Table passed into our Sample application
- Check the UEFI Spec for the parameters needed
- An example can be found in MdePkg\Library\UefiLib\Console.c :
- gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
---?image=/assets/images/slides/Slide42.JPG @title[Lab 4 :Update the C File for WaitForKey ]
Lab 4 : Update the C File for WaitForKey
Search the work space and find the following @size[.8em](MdePkg/Library/UefiLib/Console.c ) ~ ln 563:
UINTN EventIndex;
@color[green](. . . )
@color[blue](// If we encounter error, continue to read another key in.)
@color[blue](// )
if (Status != EFI_NOT_READY) {
continue;
}
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
}
@color[green](. . .)
@color[white](@size[1.2em]( Add the following to SampleApp.c))
@color[red](UINTN EventIndex; )
Print(L"System Table: 0x%p\n",SystemTable);
@color[red](Print(L"\nPress any Key to continue : \n");)
@color[red](gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex); )
Note:
Add the following "Lab 4" statements to SampleApp.c
---?image=/assets/images/slides/Slide43.JPG @title[Lab 4 :Test Compile ]
Lab 4 :Test Compile
However, this won’t compile . . . gBS and gST are not defined.
@snap[south-west span-100]
Search the MdePkg.chm for "gBS" and "gST" – they are located in UefiBootServicesTableLib.h
Add the boot services lib to SampleApp.c . . .
@color[yellow](#include <Library/UefiBootServicesTableLib.h>)
@size[.8em]((hint: Lesson B4 has the solution))
@snapend
Note:
-
However, this won’t compile … gBS and gST are not defined.
-
Search the MdePkg.chm for "gBS" and "gST" – they are located in UefiBootServicesTableLib.h
- Add the boot services lib to SampleApp.c …
- #include <Library/UefiBootServicesTableLib.h>
-
(hint: Lesson B.4 has the solution)
---?image=/assets/images/slides/Slide44.JPG @title[Lab 4 : Update SampleApp.c for gBS & gST ]
Lab 4 : Update for gBS & gST
@snap[north-west span-100]
#include <Uefi.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiLib.h>
@color[red](#include <Library/UefiBootServicesTableLib.h>)
@color[blue](// . . . )
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
@color[red](UINTN EventIndex;)
Print(L"System Table: 0x%p\n", SystemTable);
@color[red](Print(L"\nPress any Key to continue :\n"); )
@color[red](gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex); )
return EFI_SUCCESS;
}
@snap[north-east span-22]
@color[#7030a0](@size[1.4em](←) Lab 4)
@color[#7030a0](@size[1.4em](←) Lab 4)
@color[#7030a0](@size[1.4em](←) Lab 4)
@color[#7030a0](@size[1.4em](←) Lab 4)
Note:
- add:
#include <Library/UefiBootServicesTableLib.h>
SampleApp.c Should have the following for Lab 4:
#include <Uefi.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiLib.h>
// Lab 4
#include <Library/UefiBootServicesTableLib.h>
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
// Lab 4
UINTN EventIndex;
// Lab 3
Print(L"System Table: 0x%08x\n",SystemTable);
//Lab 4
Print( L"\nPress any Key to continue : \n\n");
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
return EFI_SUCCESS;
}
// End of lab
@title[Lab 4 Build and Test SampleApp]
Lab 4: Build and Test SampleApp
At the VS Command Prompt ```shell C:/FW/edk2-ws/edk2> Build C:/FW/edk2-ws/edk2> RunEmulator.bat ``` Run the application from the shell ```shell Shell> SampleApp System Table: 0x07E34018 Press any key to continue: Shell> ``` Notice that the SampleApp will wait until a key press to continue.Exit
Shell> Reset
Note:
Same as slide
---?image=/assets/images/slides/Slide_LabSec.JPG
@title[Lab 5: Creating a Simple Typewriter Function]
Lab 5: Creating a Simple Typewriter Function
Note:
---?image=/assets/images/slides/Slide47.JPG @title[Lab 5 :Create a Simple Typewriter Function]
Lab 5 : Typewriter Function
Create a Simple Typewriter Function using the SampleApp from Lab 4
Requirements:- Retrieve keys entered from keyboard (Like Lab 4)
- Print back each key entered to the console
- To Exit, press "." (DOT) and then <Enter>
Note: Same as Slide
---?image=/assets/images/slides/Slide47.JPG @title[Lab 5 :Create a Simple Typewriter Function How]
Lab 5 : Typewriter Function
Create a Simple Typewriter Function using the SampleApp from Lab 4
How:- Add a Loop using WaitForEvent with WaitForKey
- Use the ReadKeyStroke function from ConIn
- Print back each key to console
- Exit the loop when DOT "." character followed by an <Enter> key
Note: Same as Slide
@title[Lab 5 : How Hints]
Lab 5 : How Process (Hints)
- Use the same procedure as with Lab 4 to find "ReadKeyStroke" in the work space: MdePkg/Library/UefiLib/Console.c ~ ln 558
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);
- ReadKeyStroke uses buffer called EFI_INPUT_KEY ~ ln 399
- OUT EFI_INPUT_KEY *Key,
- TIP: Good Idea to zero out a buffer in your function
- Use MdePkg.chm to find ZeroMem() function
- Use ZeroMem() on your variable buffer "Key" of type EFI_INPUT_KEY
- Use Boolean flag "ExitLoop" to exit your loop once the user enters a DOT "." character.
Note: same as slide
---?image=/assets/images/slides/Slide50.JPG @title[Lab 5 :Typewriter Function Solution]
Lab 5 : Solution
@snap[north-west span-55 ]
#include <Uefi.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
// Lab 5
#include <Library/BaseMemoryLib.h>
#define CHAR_DOT 0x002E // '.' in Unicode
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINTN EventIndex;
// Lab 5
BOOLEAN ExitLoop;
EFI_INPUT_KEY Key;
// Lab 3
Print(L"System Table: 0x%p \n",SystemTable);
//Lab 4
Print( L"\nPress any Key to continue : \n\n");
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey,
&EventIndex);
@snap[north-east span-45 ]
(hint: Lesson B.5 has the solution)
// Lab 5
Print(L"Enter text. Include a dot ('.') in a \
sentence then to exit:\n "); //
ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
ExitLoop = FALSE;
do { // Do loop until "DOT" and "enter"
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
Print(L"%c", Key.UnicodeChar);
if (Key.UnicodeChar == CHAR_DOT){
ExitLoop = TRUE;
}
} while (!(Key.UnicodeChar == CHAR_LINEFEED ||
Key.UnicodeChar == CHAR_CARRIAGE_RETURN) ||
!(ExitLoop) );
Print(L"\n");
return EFI_SUCCESS;
}
Note:
Copy and paste from the following sub slide
+++ @title[Lab 5 :Typewriter Function Solution]
Lab 5 : Solution
SampleApp.c Should have the following for Lab 5:#include <Uefi.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
// Lab 5
#include <Library/BaseMemoryLib.h>
#define CHAR_DOT 0x002E // '.' in Unicode
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
UINTN EventIndex;
// Lab 5
BOOLEAN ExitLoop;
EFI_INPUT_KEY Key;
// Lab 3
Print(L"System Table: 0x%p \n",SystemTable);
//Lab 4
Print( L"\nPress any Key to continue : \n\n");
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
// Lab 5
Print(L"Enter text. Include a dot ('.') in a sentence then <Enter> to exit:\n "); //
ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
ExitLoop = FALSE;
do { // Do loop until "DOT" and "enter"
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey,&EventIndex);
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
Print(L"%c", Key.UnicodeChar);
if (Key.UnicodeChar == CHAR_DOT){
ExitLoop = TRUE;
}
} while (!(Key.UnicodeChar == CHAR_LINEFEED ||
Key.UnicodeChar == CHAR_CARRIAGE_RETURN) ||
!(ExitLoop) );
Print(L"\n");
return EFI_SUCCESS;
}
// End of lab
Note:
Same as slide
---?image=/assets/images/slides/Slide52.JPG @title[Lab 5 :Build and Test SampleApp ]
Lab 5 :Build and Test SampleApp
At the VS Command Prompt ```shell C:/FW/edk2-ws/edk2> Build C:/FW/edk2-ws/edk2> RunEmulator.bat ```Run the application from the shell
Exit
Shell> Reset
Note:
End of Lab 5
@title[Bonus Lab :Open Protocol example]
Bonus Exercise: Open Protocol Example
Write an Application using argv, argc parameters- Captures command line parameters using Open Protocol
- Will need to open SHELL_INTERFACE_PROTOCOL
- Note : Requires ShellPkg
Build SampleApp ``` C:/FW/edk2-ws/edk2> Build C:/FW/edk2-ws/edk2> RunEmulator.bat ``` Run the application from the shell ``` Shell> SampleApp test1 test2 ```
(hint: ..FW/LabSampleCode/ShellAppSample has the solution)
Note:
-
Write an Application using argv, argc parameters
- Captures command line parameters using Open Protocol
- Need to open SHELL_INTERFACE_PROTOCOL
- Note : Requires ShellPkg
-
Build SampleApp – Cd to ~/src/edk2 bash$ build
-
Copy SampleApp.efi to hda-contents
bash$ cp Build/OvmfX64/DEBUG_GCC5/X64/SampleApp.efi \
~/run-ovmf/hda-contents
-
Test by Invoking Qemu
bash$ cd ~/run-ovmf
bash$ . RunQemu.sh
-
Run the application from the shell
-
Shell> SampleApp test1 test2
-
(hint: ~FW/LabSampleCode/ShellAppSample has the solution)
---?image=assets/images/binary-strings-black2.jpg
@title[Write a EADK Application Section]
Using EADK with UEFI Application
---?image=/assets/images/slides/Slide_LabSec.JPG
@title[Lab 6: Writing UEFI Applications with EADK]
Lab 6: Writing UEFI Applications with EADK
Note:
---?image=/assets/images/slides/Slide56.JPG @title[Lab 6: With EDK II EADK]
Lab 6: With EDK II EADK
Write the same application with the same functionality as SampleApp.c using the LibC from the EADK
What libraries are needed
What differences are there using the LibC
Note:
- Write the same application with the same functionality as SampleApp.c using the LibC from the EADK
- What libraries are needed
- What differences are there using the LibC
---?image=/assets/images/slides/Slide57.JPG @title[Lab 6: EDK II using EADK]
Lab 6: EDK II using EADK
Start with the packages for EADK from edk2-libc
• /edk2-libc - AppPkg - has directory Applications
• /edk2-libc - StdLib - contains the LibC libraries
• Copy and paste directory ../FW/LabSampleCode/SampleCApp to
C:/FW/edk2-ws/edk2-libc/AppPkg/Applications/SampleCApp
Note:
-
Start with the packages for EADK
-
/edk2-libc - AppPkg - has directory Applications
-
/edk2-libc - StdLib - contains the LibC libraries
-
Copy and paste directory ~/FW/LabSampleCode/SampleCApp to C:/FW/edk2-ws/edk2-libc/AppPkg/Applications/SampleCApp
---?image=/assets/images/slides/Slide58.JPG @title[Lab 6: EDK II using EADK 02]
Lab 6: EDK II using EADK
Check out AppPkg/Applications/SampleCApp
SampleCApp.c and SampleCApp.inf
@snap[north-west span-50 ]
#include <stdio.h>
// . . .
int
main (
IN int Argc,
IN char **Argv
)
{
return 0;
}
@snap[north-east span-46 ]
[Defines]
INF_VERSION = 1.25
BASE_NAME = SampleCApp
FILE_GUID = 4ea9…
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 0.1
ENTRY_POINT = ShellCEntryLib
[Sources]
SampleCApp.c
[Packages]
StdLib/StdLib.dec
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
[LibraryClasses]
LibC
LibStdio
Note:
- EDK II using EADK
- Check out AppPkg/Applications/SampleCApp
``` #include // . . . int main ( IN int Argc, IN char **Argv ) { return 0; } [Defines] INF_VERSION = 1.25 BASE_NAME = SampleCApp FILE_GUID = 54321… MODULE_TYPE = UEFI_APPLICATION VERSION_STRING = 0.1 ENTRY_POINT = ShellCEntryLib [Sources] SampleCApp.c [Packages] StdLib/StdLib.dec MdePkg/MdePkg.dec ShellPkg/ShellPkg.dec [LibraryClasses] LibC LibStdio ```
@title[Lab 6 : Update AppPkg.dsc ]
Lab 6 : Update AppPkg.dsc
Edit the AppPkg/AppPkg.dsc and add SampleCApp.inf at the end of the components section
- (hint: search for "#### Sample Applications") - AppPkg/Applications/SampleCApp/SampleCApp.inf[Components]
#### Sample Applications.
AppPkg/Applications/Hello/Hello.inf # No LibC includes or functions.
AppPkg/Applications/Main/Main.inf # Simple invocation. No other LibC functions.
AppPkg/Applications/Enquire/Enquire.inf #
AppPkg/Applications/ArithChk/ArithChk.inf #
AppPkg/Applications/SampleCApp/SampleCApp.inf # LAB 6
@[9](Add to the Components section)
Note:
@title[Lab 6 :Build and Test SampleCApp ]
Lab 6 :Build and Test SampleCApp
Build AppPkg at the VS Command prompt ```shell C:/FW/edk2-ws/edk2> build -p AppPkg\AppPkg.dsc –m AppPkg\Applications\SampleCApp\SampleCApp.inf ``` Copy the built application to the EmulatorPkg runtime directory ```shell C:/FW/edk2-ws/edk2> copy ..\Build\AppPkg\DEBUG_VS2015x86\X64\SampleCApp.efi ..\Build\EmulatorX64\DEBUG_VS2015x86\X64 ``` Run the Emulation ```shell C:/FW/edk2-ws/edk2> RunEmulator.bat ``` Run the application SampleCapp from the shell ```shell Shell> SampleCApp ```Notice that the program will immediately unload because the main function is empty
Note:
---?image=/assets/images/slides/Slide_LabSec.JPG
@title[Lab 7: Adding Functionality to SampleCApp]
Lab 7: Adding Functionality to SampleCApp
Note:
---?image=/assets/images/slides/Slide62.JPG
@title[Lab 7: With EDK II EADK]
Lab 7: Add the same functionally from Lab 5
Note:
+++?image=/assets/images/slides/Slide63.JPG
@title[Lab 7: With EDK II EADK 02]
Lab 7: Add the same functionally from Lab 5
Note:
+++?image=/assets/images/slides/Slide64.JPG
@title[Lab 7: With EDK II EADK 03]
Lab 7: Add the same functionally from Lab 5
Note:
+++?image=/assets/images/slides/Slide65.JPG
@title[Lab 7: With EDK II EADK 04]
Lab 7: Add the same functionally from Lab 5
Note:
@title[Lab 7: With EDK II EADK solution]
@size[1.0em](Lab 7: Solution )
SampleCApp.c and SampleCApp.inf
@snap[north-west span-53 ]
@box[bg-black text-white rounded my-box-pad2 ](
@snap[north-east span-46 ]
@box[bg-black text-white rounded my-box-pad2 ](
@snap[north-east span-98 ]
@size[1.3em]("C" file)
#include <stdio.h>
// . . .
int
main (
IN int Argc,
IN char **Argv
)
{
char c;
// Lab 3
printf("System Table: %p \n", gST) ;
// Lab 4
puts("Press any Key and then to continue : ");
c=(char)getchar();
// Lab 5
puts ("Enter text. Include a dot ('.')
in a sentence then to exit:");
do {
c=(char)getchar();
} while (c != '.');
puts ("\n");
return 0;
}
@snap[north-east span-44 ]
@size[1.3em](.inf file)
[Defines]
INF_VERSION = 1.25
BASE_NAME = SampleCApp
FILE_GUID = 4ea9…
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 0.1
ENTRY_POINT = ShellCEntryLib
[Sources]
SampleCApp.c
[Packages]
StdLib/StdLib.dec
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
[LibraryClasses]
LibC
LibStdio
UefiBootServicesTableLib
Note:
@title[Lab 7 :Build and Test SampleCApp ]
Lab 7 :Build and Test SampleCApp
Build AppPkg at the VS Command prompt ```shell C:/FW/edk2-ws/edk2> build -p AppPkg\AppPkg.dsc –m AppPkg\Applications\SampleCApp\SampleCApp.inf ``` Copy the built application to the EmulatorPkg runtime directory ```shell C:/FW/edk2-ws/edk2> copy ..\Build\AppPkg\DEBUG_VS2015x86\X64\SampleCApp.efi ..\Build\EmulatorX64\DEBUG_VS2015x86\X64 ``` Run the Emulation ```shell C:/FW/edk2-ws/edk2> RunEmulator.bat ``` Run the application SampleCapp from the shell ```shell Shell> SampleCApp Press any Key and then to Continue :Enter text. Include a dot (‘.’) in a sentence then to exit: Some text here, then a DOT. Shell>
Note:
---
@title[Summary]
<BR>
### <p align="center"><span class="gold" >Summary </span></p><br>
<br>
<ul style="list-style-type:none">
<li>@fa[certificate gp-bullet-green]<span style="font-size:0.9em"> UEFI Application with PCDs</span> </li>
<li>@fa[certificate gp-bullet-cyan]<span style="font-size:0.9em"> Simple UEFI Application</span></li>
<li>@fa[certificate gp-bullet-yellow]<span style="font-size:0.9em"> Add functionality to UEFI Application</span> </li>
<li>@fa[certificate gp-bullet-magenta]<span style="font-size:0.9em"> Using EADK with UEFI Application</span></li>
</ul>
---?image=assets/images/gitpitch-audience.jpg
@title[Questions]
<br>
![Questions](/assets/images/questions.JPG)
---?image=assets/images/gitpitch-audience.jpg
@title[Logo Slide]
<br><br><br>
![Logo Slide](/assets/images/TianocoreLogo.png =10x)
---
@title[Acknowledgements]
#### <p align="center"><span class="gold" >Acknowledgements</span></p>
```c++
/**
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:
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.
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 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) 2020, Intel Corporation. All rights reserved.
**/