<div class="xblock xblock-public_view xblock-public_view-vertical" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-init="VerticalStudentView" data-runtime-class="LmsRuntime" data-runtime-version="1" data-block-type="vertical" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@vertical+block@6bef04b7622b4df2bd7e56cd8b077609" data-request-token="d09c990e090a11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@markdown+block@7a617a7f6f0648299d14ad7a5cd4cff1">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@markdown+block@7a617a7f6f0648299d14ad7a5cd4cff1" data-request-token="d09c990e090a11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><p>In the development preparation section we built EDKII the first time using the <code>./build.sh</code> script for the OVMF package. Now it is time to dive deeper into the EDKII build process and understand what happened behind the scenes.</p>
<h2>How to get documentation of EDKII build process</h2>
<p>The most recent documentation of the EDKII build process is stored as code in the TianoCore Documentation respository called <a href="https://github.com/tianocore-docs/edk2-BuildSpecification">edk2-BuildSpecification</a>.
The easiest way to explore it without installing lot of dependencies or using gitbook would be cloning repository and hosting a local HTTP server:</p>
<div class="codehilite">
<pre><span></span><code>git clone https://github.com/tianocore-docs/edk2-BuildSpecification.git
<span class="nb">cd</span> edk2-BuildSpecification
git checkout gh-pages
python3 -m http.server
</code></pre>
</div>
<p>Then open <code>0.0.0.0:8000</code> in web browser.</p>
<h2>Key environment variables</h2>
<ul>
<li><code>WORKSPACE</code> - environment variable which keeps the name of the directory in which the build process is performed</li>
<li><code>PACKAGES_PATH</code> - environment variable which keeps package search paths. Searching always usees the first match, where <code>WORKSPACE</code> is first directory to be searched</li>
<li><code>EDK_TOOLS_PATH</code> - environment was already discussed, but it points to the <code>BaseTools</code> and <code>Conf</code> directories which contain build tools and their configuration</li>
</ul>
<p>The EDKII build system supports Windows, Linux, macOS, and various compilers. You may check <code>./BaseTools/Conf/tools_def.template</code> to see what development environments are supported.
Please note that despite the huge number of environments not all of them work out-of-the-box.</p>
<p>To simplify environment variables setup, EDKII provides the <code>edksetup.sh</code> script for UNIX-like environments. To use it type:</p>
<div class="codehilite">
<pre><span></span><code><span class="nb">source</span> edksetup.sh
</code></pre>
</div>
<h2>Key file extensions</h2>
<ul>
<li><code>DEC</code> - EDKII Declaration (DEC) file format described in <a href="https://edk2-docs.gitbook.io/edk-ii-dec-specification/v/release-1.27-3/">edk2-DecSpecification (1.27-3)</a>. This file declares information about what is provided in the package. An EDKII package is a collection of like content.</li>
<li><code>DSC</code> - EDKII Platform Description (DSC) file format described in <a href="https://edk2-docs.gitbook.io/edk-ii-dsc-specification/v/release-1.28-2/">edk2-DscSpecification (1.28-2)</a>. This file describes what and how modules, libraries and components are to be built, as well as defining library instances which will be used when linking EDKII modules.</li>
<li><code>FDF</code> - EDKII Flash Description (FDF) file format described in <a href="https://edk2-docs.gitbook.io/edk-ii-fdf-specification/v/release-1.28.01/">edk2-FdfSpecification (1.28.01</a>. This file is used to define the content and binary image layouts for firmware images, update capsules and PCI option ROMs. </li>
<li><code>INF</code> - EDKII build information (INF) file format described in <a href="https://edk2-docs.gitbook.io/edk-ii-inf-specification/v/release-1.27/">edk2-InfSpecification (1.27)</a>. This file is used to describe various modules binary, source and mixed, also intermediate product of EDKII build system. This file format is fundamental component of build system since it describe most basic unit of EDKII - modules.</li>
<li><code>IDF</code> - EDKII Image Description (IDF) files used for creating HII Image Packs used for graphical content presentation.</li>
<li><code>UNI</code> - EDKII Unicode string file format described in <a href="https://edk2-docs.gitbook.io/edk-ii-uni-specification/v/release-1.40/">edk2-UniSpecification (1.40)</a>. This file is used for mapping token names to localized strings that are identified by an RFC4646 language code - in this way EDKII support switching between multiple languages.</li>
<li><code>VFR</code> - EDKII Visual Forms Representation file format described in <a href="https://edk2-docs.gitbook.io/edk-ii-vfr-specification/v/release-1.92/">edk2-VfrSpecification (1.92)</a>. This is the source code format that is used by developers to create a user interface with varying pieces of data or questions. This is later compiled into a binary encoding IFR (Internal Forms Representation) that is used for the representation of user interface pages.</li>
</ul>
<p><code>DSC</code> are most important for build process since it define our target platform.</p>
<p>Please note we tried to use links to the most recent, already generated documentation at the point of creation of this exercise, but looking at published material may be misleading since the repository may contain newer content. Feel free to check the available version as well as associated Github repositories.</p>
<h3>Exercise #1</h3>
<p>Find all file types mentioned above in EDKII source tree and check its content.</p>
<h2>Build command</h2>
<p>EDKII build system is quite sophisticated and its build command provide a lot of parameters.</p>
<h3>Exercise #2</h3>
<p>After setting up EDKII environment variables please check build command parameters by calling help <code>build --help</code></p>
<p>Most important parameters at in this section of the course are: </p>
<ul>
<li><code>-p PLATFORMFILE</code> - Build the platform specified by the DSC file name </li>
<li><code>-b BUILDTARGET</code> - DEBUG or RELEASE build target </li>
<li><code>-t TOOLCHAIN</code> - Using the toolchain tagname to build the platform defined in tools_def.template, in this course we use GCC5 </li>
<li><code>-n THREADNUMBER</code> - Build the platform using multi-threaded compiler with defined number of threads, typically half of available CPU threads </li>
<li><code>-a ARCH</code> - ARCH is one of list: IA32, X64, ARM, AARCH64, RISCV64 or EBC </li>
</ul>
<p>There is no need to provide those paramters every time as input to <code>build</code> command. Default parameters can be determine in <code>./Conf/target.txt</code>.
Please note the <code>build</code> command can also run just part of the build process by getting a stage name as the final parameter. The most important stages are:</p>
<ul>
<li><code>all</code> - go through all build stages, this is default if no other stage option is given </li>
<li><code>fds</code> - use platform FDF to build final binary fimage. Useful if we changed FDF file and we want to rebuild final binary </li>
<li><code>genc</code> - autogenerate all necessary code files </li>
<li><code>genmake</code> - autogenerate all necessary makefile files </li>
<li><code>clean</code> - remove all binary products of build process, but keep intermediate autogenerated files </li>
<li><code>cleanall</code> - clean everything from platform target directory </li>
</ul>
<p>Despite all these possibilities, frequent building and code changes may get you into a weird state, which gives hard to diagnose compilation errors. To resolve that typically <code>cleanall</code> is required.</p>
<h3>Exercise #3</h3>
<ol>
<li>Setup environment variables by running "<code>source edksetup.sh</code>"</li>
<li>Find DSC file for OVMF X64</li>
<li>Run the <code>build</code> process, setting all the most important command line parameters</li>
</ol>
<p>Final result should look tell us how much space each Firmware Volume takes:</p>
<pre><code>(...)
FV Space Information
SECFV [19%Full] 212992 (0x34000) total, 42432 (0xa5c0) used, 170560 (0x29a40) free
PEIFV [22%Full] 917504 (0xe0000) total, 210152 (0x334e8) used, 707352 (0xacb18) free
DXEFV [33%Full] 12582912 (0xc00000) total, 4212944 (0x4048d0) used, 8369968 (0x7fb730) free
FVMAIN_COMPACT [35%Full] 3440640 (0x348000) total, 1233928 (0x12d408) used, 2206712 (0x21abf8) free
- Done -
Build end time: 00:30:41, Apr.05 2022
Build total time: 00:01:17
</code></pre>
<p>Our firmware image can be found in <code>Build/OvmfX64/BUILDTARGET_TOOLCHAIN/FV/OVMF.fd</code></p>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@problem+block@3d89bda1f28743c19acd63e8db59a0d4">
<div class="xblock xblock-public_view xblock-public_view-problem xmodule_display xmodule_ProblemBlock" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="problem" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@problem+block@3d89bda1f28743c19acd63e8db59a0d4" data-request-token="d09c990e090a11efabb30242ac12000b" data-graded="True" data-has-score="True">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Checkboxes is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
<div class="vert vert-2" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@done+block@28683e2362254bedb9395bd41ea5ded1">
<div class="xblock xblock-public_view xblock-public_view-done" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="done" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@done+block@28683e2362254bedb9395bd41ea5ded1" data-request-token="d09c990e090a11efabb30242ac12000b" data-graded="True" data-has-score="True">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Completion is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
<div class="vert vert-3" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@discussion+block@5806476cf9dc4877832c74c68e6e4018">
<div class="xblock xblock-public_view xblock-public_view-discussion" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="discussion" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@discussion+block@5806476cf9dc4877832c74c68e6e4018" data-request-token="d09c990e090a11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Discussion is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
</div>
<script type="text/javascript">
(function (require) {
require(['/static/js/dateutil_factory.be68acdff619.js?raw'], function () {
require(['js/dateutil_factory'], function (DateUtilFactory) {
DateUtilFactory.transform('.localized-datetime');
});
});
}).call(this, require || RequireJS.require);
</script>
<script>
function emit_event(message) {
parent.postMessage(message, '*');
}
</script>
</div>
<div class="xblock xblock-public_view xblock-public_view-vertical" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-init="VerticalStudentView" data-runtime-class="LmsRuntime" data-runtime-version="1" data-block-type="vertical" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@vertical+block@b569d0f6eae94153850d1e4237ee21df" data-request-token="d09c990e090a11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@markdown+block@bdc1306286b94ab6a694d441b6862c91">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@markdown+block@bdc1306286b94ab6a694d441b6862c91" data-request-token="d09c990e090a11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><p>Let's run results of build process:</p>
<div class="codehilite">
<pre><span></span><code>qemu-system-x86_64 -drive <span class="k">if</span><span class="o">=</span>pflash,format<span class="o">=</span>raw,file<span class="o">=</span>Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd -nographic
</code></pre>
</div>
<p>After iPXE timeout we should boot to UEFI Shell command line prompt. Please note that to leave emulator you can use special command for which help can be found using <code>Ctrl-a h</code>.</p>
<h2>Exercise #4</h2>
<p>Please repeat steps from Exercise #3, but instead parameters to <code>build</code> command use <code>Conf/target.txt</code> file. If you modify <code>Conf/target.txt</code> correctly <code>build</code> command should run without problems and build fresh <code>OVMF.fd</code>.</p>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@problem+block@aacb350e5c4f4a328d84c74d7b025840">
<div class="xblock xblock-public_view xblock-public_view-problem xmodule_display xmodule_ProblemBlock" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="problem" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@problem+block@aacb350e5c4f4a328d84c74d7b025840" data-request-token="d09c990e090a11efabb30242ac12000b" data-graded="True" data-has-score="True">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Multiple Choice is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
<div class="vert vert-2" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@done+block@881b5cab696f494b8e6af7b90632573e">
<div class="xblock xblock-public_view xblock-public_view-done" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="done" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@done+block@881b5cab696f494b8e6af7b90632573e" data-request-token="d09c990e090a11efabb30242ac12000b" data-graded="True" data-has-score="True">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Completion is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
<div class="vert vert-3" data-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@discussion+block@095d00bdb26d437db806fe74d72ba705">
<div class="xblock xblock-public_view xblock-public_view-discussion" data-course-id="course-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1" data-block-type="discussion" data-usage-id="block-v1:OpenSecurityTraining2+4021_Intro_UEFI+2022_v1+type@discussion+block@095d00bdb26d437db806fe74d72ba705" data-request-token="d09c990e090a11efabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="page-banner"><div class="alert alert-warning"><span class="icon icon-alert fa fa fa-warning" aria-hidden="true"></span><div class="message-content">Discussion is only accessible to enrolled learners. Sign in or register, and enroll in this course to view it.</div></div></div>
</div>
</div>
</div>
<script type="text/javascript">
(function (require) {
require(['/static/js/dateutil_factory.be68acdff619.js?raw'], function () {
require(['js/dateutil_factory'], function (DateUtilFactory) {
DateUtilFactory.transform('.localized-datetime');
});
});
}).call(this, require || RequireJS.require);
</script>
<script>
function emit_event(message) {
parent.postMessage(message, '*');
}
</script>
</div>