Skip to content

Latest commit

 

History

History

Lesson_01

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

In last lesson we've built an app that was already included in the TianoCore sources.

Let's work our way through to our own app. We will be working on UEFI app that can be run in UEFI shell.

Create directory for our app:

mkdir SimplestApp

Then create *.c source file for our app with the folowing content:

$ cat SimplestApp/SimplestApp.c

EFI_STATUS
EFIAPI
UefiMain (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EFI_SUCCESS;
}

Then we need to create edk2 app configuration file. This configuration in edk2 is represented in the *.inf format. INF file can have several sections:

  • Defines
  • Sources
  • Packages
  • LibraryClasses
  • Guids
  • Ppis
  • Protocols
  • FeaturePcd
  • Pcd
  • ...

But right now for our minimal example we're interested in the 3 of those:

  • Defines - this section contatins some basic module description. In this section:

BASE_NAME - our app name

FILE_GUID - as was said earlier UEFI uses GUID numbers for identification of the components. You could use free online GUID generator to get random GUID https://www.guidgenerator.com/ or simply use uuidgen command line utility:

$ uuidgen
e7218aab-998e-4d88-af9b-9573a5bf90ea

MODULE_TYPE - we want to build an application that can be run from the UEFI shell, so we use UEFI_APPLICATION here. UEFI application is like a simple program that you can run from shell. It is getting loaded to some memory address, executes and returns something, after that app memory would be freed again. For example other possible value here is UEFI_DRIVER - the difference is when you load a driver it keeps staying in memory even after its execution. Other values are listed here: https://edk2-docs.gitbook.io/edk-ii-inf-specification/appendix_f_module_types

ENTRY_POINT - name of the main function in our *.c source file. As it was UefiMain this is the value that we write here.

  • Sources - source files for our edk2 module
  • LibraryClasses - we need to include UefiApplicationEntryPoint library class for our minimal example
  • Packages - MdePkg/MdePkg.dec is edk2 package with basic UEFI services. It includes UefiApplicationEntryPoint that we need to compile our package.

vi SimplestApp/SimplestApp.inf

[Defines]
  INF_VERSION                    = 1.25
  BASE_NAME                      = SimplestApp
  FILE_GUID                      = 4a298956-fbe0-47fb-ae3a-2d5a0a959a26
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = UefiMain

[Sources]
  SimplestApp.c

[Packages]
  MdePkg/MdePkg.dec

[LibraryClasses]
  UefiApplicationEntryPoint

Full specification for the "Module Information (INF) File" can be found under https://edk2-docs.gitbook.io/edk-ii-inf-specification/

After the creation of the INF file we need to include our app to some package so we could build it.

We don't have our own package, so let's include it to OvmfPkg/OvmfPkgX64.dsc that we've compiled earlier. Add a path to our app *.inf file in the components section.

 ################################################################################
 [Components]
+  SimplestApp/SimplestApp.inf
   OvmfPkg/ResetVector/ResetVector.inf

Then build OVMF:

build --platform=OvmfPkg/OvmfPkgX64.dsc --arch=X64 --buildtarget=RELEASE --tagname=GCC5

Our compiled app would be in a directory Build/OvmfX64/RELEASE_GCC5/X64:

$ ls -lh Build/OvmfX64/RELEASE_GCC5/X64/SimplestApp.efi
-rw-r--r-- 1 kostr kostr 832 Jun 13 10:14 Build/OvmfX64/RELEASE_GCC5/X64/SimplestApp.efi

Create a folder that we would populate to UEFI shell and copy our app into it:

mkdir ~/UEFI_disk
cp Build/OvmfX64/RELEASE_GCC5/X64/SimplestApp.efi ~/UEFI_disk

Now lets run OVMF with this folder included:

$ qemu-system-x86_64 -drive if=pflash,format=raw,file=Build/OvmfX64/RELEASE_GCC5/FV/OVMF.fd \
                     -drive format=raw,file=fat:rw:~/UEFI_disk \
                     -nographic \
                     -net none

Hopefully you'll see something like this:

UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 (EDK II, 0x00010000)
Mapping table
      FS0: Alias(s):HD0a1:;BLK1:
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
     BLK2: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
Press ESC in 3 seconds to skip startup.nsh or any other key to continue.

As you can see we have new rows in our mapping table. Our app would be under FS0. Lets mount this filesystem and execute our app.

Shell> fs0:
FS0:\> SimplestApp.efi
FS0:\>