EDK2: Difference between revisions

349 bytes added ,  29 days ago
m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
m (UefiMain.c didn't compile. Added ; after line 17. There was also to fee bytes allocated as str2 is L-string.)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(3 intermediate revisions by 3 users not shown)
Line 2:
EDK2 is the official development environment for [[UEFI]] applications. It is developed by the open-source Tianocore project, of which Intel, HP, and Microsoft are the primary contributors. Although it may be bigger than [[GNU-EFI]], it has more features, hence, some OS developers may prefer it over GNU-EFI.
 
===What is EDK2?===
EDK2 is full on implementation of the [[UEFI]] spec. It contains the Open Virtual Machine Firmware (OVMF) UEFI firmware package, which is primarily targeted at [[QEMU]], and is used by many OS developers to test out their UEFI applications. It also has [[ARM]] and [[AArch64]] firmware packages for QEMU and various boards, and [[RISC-V]] firmware packages for various [[HiFive]] boards. It also has tools for UEFI driver developers, but that is outside the scope of this wiki.
 
Of most interest the OS developers is the UEFI library and the EDK2 build system. This article will show you the structure of EDK2, how to build firmware for QEMU and real machines, and how to build UEFI applications.
 
===Structure of EDK2===
EDK2 is made up of multiple repos, all of which can be found at [https://github.com/tianocore https://github.com/tianocore]. The main ones are:
 
Line 17:
 
EDK2 itself is written in C with some Python, and is licensed under the BSD 2 Clause + Patent license. The blobs are subject to their own licenses.
====Directory structure====
EDK2 is split up into multiple subdirectories, where each one normally contains a "Package". The OvmfPkg subdirectory contains OVMF, the MdePkg subdirectory contains the UEFI library, and so on. Each one of these contains a file ending in .dsc. This file describes the package inside of the folder, and contains things such as dependencies, different components, and so on. Each component is described its own file that contains sources, application type, and so on.
TODO: Describe this in more detail
===Building EDK2's base===
No matter what you are trying to build from EDK2, these steps must be completed. First, you must decide if you want to only build stuff inside of the main EDK2 repo, or if you also want stuff from edk2-platforms. Note that these guides assume you are on a Linux system (Windows Subsystem for Linux is OK)
====Building without edk2-platforms====
If you only want the UEFI library or virtual machine firmware, then this guide will suffice. Make sure you have all the dependencies installed first:
<sourcesyntaxhighlight lang="bash">
sudo apt install build-essential git python2 uuid-dev nasm acpica-tools # Or whatever your package manager is
</syntaxhighlight>
</source>
First, we must clone EDK2
<sourcesyntaxhighlight lang="bash">
git clone https://github.com/tianocore/edk2.git
</syntaxhighlight>
</source>
Note that this is the latest non-stable source. If you want the stable source then run:
<sourcesyntaxhighlight lang="bash">
git clone https://github.com/tianocore/edk2.git -b"stable/202011"
</syntaxhighlight>
</source>
or whatever is appropriate at the time you are reading this. After that, we now must clone the submodules
<sourcesyntaxhighlight lang="bash">
cd edk2
git submodule update --init
</syntaxhighlight>
</source>
Then, we need to setup the environment for EDK2
<sourcesyntaxhighlight lang="bash">
export EDK_TOOLS_PATH=$PWD/BaseTools
# If you are compiling for ARM, then this is needed
Line 51:
# Run this no matter what you are compiling for
source edksetup.sh
</syntaxhighlight>
</source>
The last step generates various configuration files and sets up some variables. Note that edksetup.sh must be sourced, as its variables must persist.
Now we need to build the base tools
<sourcesyntaxhighlight lang="bash">
make -C BaseTools
</syntaxhighlight>
</source>
And lastly, we must actually build EDK2 using its Python build script.
<sourcesyntaxhighlight lang="bash">
build -a YOUR_ARCH -t GCC5 -p YOUR_PACKAGE
</syntaxhighlight>
</source>
YOUR_ARCH can be IA32, X64, AARCH64, ARM, or RISCV64. Note that not all packages compile for all architectures. YOUR_PACKAGE must point to a package in the source tree. Further guides in this article will tell you what -p option to pass to EDK2's build script
====Building with edk2-platforms====
If you actually want firmware that runs on real hardware, then you must perform the following steps instead of the one above
 
First, we need to create our workspace folder
<sourcesyntaxhighlight lang="bash">
mkdir edk2 && cd edk2
export WORKSPACE=$PWD
</syntaxhighlight>
</source>
Now we need to clone the source to all repos. edk2-non-osi is optional depending on the platform you are building for, but I would recommend downloading it anyway
<sourcesyntaxhighlight lang="bash">
git clone https://github.com/tianocore/edk2.git -b"stable/202011"
git clone https://github.com/tianocore/edk2-platforms.git
Line 77:
cd edk2 && git submodule update --init
cd ../edk2-platforms && git submodule update --init && cd ..
</syntaxhighlight>
</source>
We need to let EDK2's build system know where these folders are. We'll also setup a couple other variables as well
<sourcesyntaxhighlight lang="bash">
export EDK_TOOLS_PATH="$PWD/BaseTools"
export PACKAGES_PATH="$PWD/edk2:$PWD/edk2-platforms:$PWD/edk2-non-osi"
</syntaxhighlight>
</source>
We now must setup the environment now
<sourcesyntaxhighlight lang="bash">
. edk2/edksetup.sh
make -C edk2/BaseTools
</syntaxhighlight>
</source>
After that, building is exactly like before. To build for a certain platform in edk2-platforms, simply find the relevant .dsc file.
===Building an EDK2 UEFI application===
Once you have EDK2's base built, building UEFI applications is super easy. As OS developers, the main package will be working with is MdeModulePkg, a complete UEFI wrapper library.
 
First, we must create a directory that contains our application. We'll create it inside of the main EDK2 directory, like this
<sourcesyntaxhighlight lang="bash">
cd edk2
mkdir MyEfiApp
</syntaxhighlight>
</source>
Now, create a file named MyEfiApp.inf in the MyEfiApp directory. Give it the following contents
<sourcesyntaxhighlight lang="ini">
[Defines]
INF_VERSION = 1.25
Line 127:
[Pcd]
 
</syntaxhighlight>
</source>
Create a file called UefiMain.c in the same directory MyEfiApp.inf, and give it the following contents
<sourcesyntaxhighlight lang="c">
#include <Uefi.h>
#include <Library/UefiLib.h>
Line 152:
return EFI_SUCCESS;
}
</syntaxhighlight>
</source>
 
Now run edksetup.sh if need be. After that, find a "Components" section MdeModulePkg/MdeModulePkg.dsc, and add this to it
<sourcesyntaxhighlight lang="ini">
[Components]
...
MyEfiApp/MyEfiApp.inf
</syntaxhighlight>
</source>
After that, call EDK2's build system like this to build MyEfiApp
<sourcesyntaxhighlight lang="bash">
build -a YOUR_ARCH -t GCC5 -p MdeModulePkg/MdeModulePkg.dsc
</syntaxhighlight>
</source>
Finally, in the folder Build/MdeModule/DEBUG_GCC5/YOUR_ARCH, there should be a file named MyEfiApp.efi.
 
===Building OVMF and ArmVirt===
Building OVMF and ArmVirtPkg is easy, after setting up EDK2, run the following for OVMF:
<sourcesyntaxhighlight lang="bash">
build -a YOUR_ARCH -t GCC5 -p OvmfPkg/OvmfPkgYOUR_ARCH.dsc
</syntaxhighlight>
</source>
YOUR_ARCH can only be IA32 or X64 for OVMF. For ArmVirtPkg, run this instead:
<sourcesyntaxhighlight lang="bash">
build -a YOUR_ARCH -t GCC5 -p ArmVirtPkg/ArmVirtQemu.dsc
</syntaxhighlight>
</source>
YOUR_ARCH can only be ARM or AARCH64. After this,, the firmware will be output in for OVMF Build/OvmfYOUR_ARCH/DEBUG_GCC5/FV, or for ArmVirtPkg Build/ArmVirtQemu-YOUR_ARCH/DEBUG_GCC5/FV
 
[[Category:UEFI]]
[[Category:Firmware]]