<div class="xblock xblock-public_view xblock-public_view-vertical" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-init="VerticalStudentView" data-runtime-class="LmsRuntime" data-runtime-version="1" data-block-type="vertical" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@vertical+block@17657869ce6e4ba683ebce25c07426ae" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@c42ec24a4d6d4098ac55dc5f62dbf87c">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@c42ec24a4d6d4098ac55dc5f62dbf87c" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><p>Let's make sure we have:</p>
<ul>
<li>Source Level Debugging enabled (please check Practice #2)</li>
<li>Gathered whole <code>debug.log</code> from boot process</li>
<li>Run QEMU</li>
</ul>
<div class="codehilite">
<pre><span></span><code>qemu-system-x86_64 -nographic -bios Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd -chardev file,path<span class="o">=</span>debug.log,id<span class="o">=</span>edk2-debug -device isa-debugcon,iobase<span class="o">=</span>0x402,chardev<span class="o">=</span>edk2-debug -net none
</code></pre>
</div>
<ul>
<li>Wait until <code>Shell></code> and exit <code>Ctrl-a x</code>.</li>
<li>Debug log should be in known file <code>debug.log</code></li>
</ul>
<h2>Exercise #1: Find where each UEFI boot phase starts</h2>
<ul>
<li>Grep for case insensitive <code>SEC</code>, <code>PEI</code>, <code>DXE</code> and <code>BDS</code></li>
</ul>
<h3>SEC</h3>
<ul>
<li>There is only one entry talking about SEC phase, shown below. The other entries are not related to the UEFI phase:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>SecCoreStartupWithStack<span class="o">(</span>0xFFFCC000, 0x820000<span class="o">)</span>
</code></pre>
</div>
<ul>
<li>Please note the above log entry, so we can explore the C code related to it in further exercises in this lab.</li>
</ul>
<h3>PEI</h3>
<ul>
<li>When looking for PEI we get way more occurances, including a lot of PEIM loading, PPI notifications, and discovery of volumes.</li>
<li>The first occurance of Pei is in following log:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>DiscoverPeimsAndOrderWithApriori<span class="o">()</span>: Found 0x7 PEI FFS files <span class="k">in</span> the 0th FV
</code></pre>
</div>
<ul>
<li>But, is it really the PEI phase start? We will try to figure this out in the next exercise.</li>
</ul>
<h3>DXE</h3>
<ul>
<li>The first occurance is loading of the DXE IPL (Initial Program Loader), which prints the following log:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>DXE IPL Entry
</code></pre>
</div>
<h3>BDS</h3>
<ul>
<li>The first occurance is loading of the BDS DXE driver, which prints the following log:</li>
</ul>
<div class="codehilite">
<pre><span></span><code><span class="o">[</span>Bds<span class="o">]</span> Entry...
</code></pre>
</div>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@done+block@572fd0a6f5374acf9320391cb0685f11">
<div class="xblock xblock-public_view xblock-public_view-done" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="done" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@done+block@572fd0a6f5374acf9320391cb0685f11" data-request-token="980f71f4fef311eeabb30242ac12000b" 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-2" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@discussion+block@495d84919ea04ee7b8c683e88e22cb07">
<div class="xblock xblock-public_view xblock-public_view-discussion" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="discussion" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@discussion+block@495d84919ea04ee7b8c683e88e22cb07" data-request-token="980f71f4fef311eeabb30242ac12000b" 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+Arch4021_intro_UEFI+2023_v1" data-init="VerticalStudentView" data-runtime-class="LmsRuntime" data-runtime-version="1" data-block-type="vertical" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@vertical+block@9c11a3b908644634bf6548aa492201b7" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@7a97acc3db3e4c3382ccf463f7592aca">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@7a97acc3db3e4c3382ccf463f7592aca" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><p>Let's step through the OVMF SEC phase.</p>
<h2>Exercise #2: Break in SEC at previous logging point and prepare to step through to the PEI hand-off</h2>
<ul>
<li>Return to the <code>OvmfPkg/Sec/SecMain.c</code> file that you added a debug statement
to in <a href="https://beta.ost2.fyi/courses/course-v1:OpenSecurityTraining2+Arch4021+2022_v2/jump_to_id/3f7de0b5c78c4e0ebbe336219bbd7daa">Practice #2: EDK II Debugging -> Exercise #2: Debugging by printing</a>.</li>
<li>Search in this file to find the place where control is handed over from SEC
to PEI core.</li>
<li>Use the steps from <a href="https://beta.ost2.fyi/courses/course-v1:OpenSecurityTraining2+Arch4021+2022_v2/jump_to_id/5cde3f53f21c4b838c823391f70ecd77">Practice #2: EDK II Debugging -> Exercise #3: Debugging
using GDB</a> to break at the beginning of the function where control is handed
off from SEC to PEI.
<ul>
<li>Feel free to use <strong>tui enable</strong> in gdb since code comments may help identify place
where control is transferred.</li>
</ul></li>
<li>Please write down the type of the function pointer called during the hand off
from SEC to PEI (we will refer to it as <code><SEC_TO_PEI_FPTR_TYPE></code>)</li>
<li>If you continue step into the PEI core, GDB will not be able to determine the
source code it is associated with, because of that we have to load the
appropriate symbols.</li>
</ul>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@bfa7049164a242b599a88e71420b964d">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@bfa7049164a242b599a88e71420b964d" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><h2>Exercise #3: Load PEI core symbols by finding information in build output files</h2>
<ul>
<li>Search for the location where the function pointer type <code><SEC_TO_PEI_FPTR_TYPE></code> is <em>defined</em>, not just <em>used</em>.</li>
</ul>
<div class="codehilite">
<pre><span></span><code>grep -r <SEC_TO_PEI_FPTR_TYPE>
</code></pre>
</div>
<ul>
<li>From this you should find a header file that has the definition. Translating that function pointer. You should look into header file for parameters.</li>
<li><p>But what is the actual target of that function pointer in our case? Here the complexity of EDKII and UEFI is added to the typical complexity of trying to follow indirect control flow through function pointers in C codebases:</p>
<ul>
<li><p>Rather than search through every usage of the function pointer, let's instead focus on the parameters that the function must take, as described in the definition we've already found. There are two of them. And we can use the following advanced grep magic to find other locations where those parameters occur right next to each other (as we would expect they would in the target function which implements the same interface as the function pointer.)</p>
<div class="codehilite">
<pre><span></span><code>grep <span class="s2">"IN CONST <FIRST_PARAM_TYPE>"</span> --include<span class="o">=</span><span class="se">\*</span>.c . -r -A <span class="m">1</span> --exclude-dir<span class="o">=</span>Build<span class="p">|</span>grep <span class="s2">"IN CONST <SECOND_PARAM_TYPE>"</span> -B <span class="m">1</span>
</code></pre>
</div></li>
<li><p>To explain the above, it says: please look for <code><FIRST_PARAM_TYPE></code> recursively (<code>-r</code>) in all C files only (<code>--include=\*.c</code> (so this excludes our definition in the header that we already found)), except the Build directory (<code>--exclude-dir=Build</code>) and show one line after the occurrence. Then we pipe the result and grep the output buffer looking for occurrences of <code><SECOND_PARAM_TYPE></code>, which should happen in the subsequent line, and when found, print the occurrence and one line before.</p></li>
<li>Based on this you should have found a single file that has the same two parameters that are used in the <code><SEC_TO_PEI_FPTR_TYPE></code> function pointer.</li>
</ul></li>
<li><p>Now let's find what the <code>BASE_NAME</code> is according to the INF file that is used for compilation of code this. The relevant INF file is typically found in the same directory or one level above. But how would we know we are looking at the correct INF file? You should see that it contains our C source code file name in the <code>[Sources]</code> section.</p></li>
<li>Finally we will look for the <code>BASE_NAME</code> of this module in map files, to find the BaseAddress where it is loaded in memory, which can be used to load debug the debug binary</li>
</ul>
<div class="codehilite">
<pre><span></span><code>grep <BASE_NAME> --include<span class="o">=</span><span class="se">\*</span>.map . -rw<span class="p">|</span>grep BaseAddress
</code></pre>
</div>
<ul>
<li>We are a little bit lucky in the end, because we dealing with a core UEFI phase module, not some random driver. That's why it is visible in a map file.</li>
<li>Use the steps you learned before in "Practice #2: EDK II Debugging" -> "Debugging using GDB" Exercise #3, to load the debug symbols for the <BASE_NAME>.debug file.</li>
<li>Step from the SecMain.c code into the PEI core code.</li>
</ul>
</div>
</div>
</div>
<div class="vert vert-2" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@done+block@6c2ab0da519f4a2c8e20fe710a20a39d">
<div class="xblock xblock-public_view xblock-public_view-done" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="done" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@done+block@6c2ab0da519f4a2c8e20fe710a20a39d" data-request-token="980f71f4fef311eeabb30242ac12000b" 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+Arch4021_intro_UEFI+2023_v1+type@discussion+block@3b1aaf703aeb4785991035da91d327e6">
<div class="xblock xblock-public_view xblock-public_view-discussion" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="discussion" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@discussion+block@3b1aaf703aeb4785991035da91d327e6" data-request-token="980f71f4fef311eeabb30242ac12000b" 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+Arch4021_intro_UEFI+2023_v1" data-init="VerticalStudentView" data-runtime-class="LmsRuntime" data-runtime-version="1" data-block-type="vertical" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@vertical+block@17cdee277c934cb9bd0836d50953ba02" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@aa619d320f204d5da581c9c62764ef37">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@aa619d320f204d5da581c9c62764ef37" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><h2>Exercise #4: Jump to PEI</h2>
<ul>
<li>Please check <code>./Build/OvmfX64/DEBUG_GCC5/Ovmf.map</code> to find PEI base address, so we can load into open session new file and symbols</li>
<li>Let's start QEMU:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>qemu-system-x86_64 -nographic -bios Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd -chardev file,path<span class="o">=</span>debug.log,id<span class="o">=</span>edk2-debug -device isa-debugcon,iobase<span class="o">=</span>0x402,chardev<span class="o">=</span>edk2-debug -net none -s -S
</code></pre>
</div>
<ul>
<li>Let's start GDB and load symbols:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>add-symbol-file Build/OvmfX64/DEBUG_GCC5/X64/SecMain.debug <span class="o">(</span>0x00fffcc094+0x0000000000000240<span class="o">)</span> -s .data <span class="o">(</span>0x00fffcc094+0x00000000000088c0<span class="o">)</span>
add-symbol-file Build/OvmfX64/DEBUG_GCC5/X64/PeiCore.debug <span class="o">(</span>0x0000820140+0x0000000000000240<span class="o">)</span> -s .data <span class="o">(</span>0x0000820140+0x000000000000af40<span class="o">)</span>
target remote :1234
<span class="nb">break</span> SecStartupPhase2
</code></pre>
</div>
<p>Please note above addresses could change, if you using different code base or different compilation parameters.</p>
<ul>
<li>Step into (gdb <code>s</code>) <code>PeiCoreEntryPoint</code> and you are in PEI phase</li>
</ul>
<h2>Exercise #5: Review PEI debug.log</h2>
<ul>
<li>Continue debug session from Exercise #6 by stepping in (gdb <code>si</code>) <code>ProcessModuleEntryPointList</code> and then you can step over (gdb <code>n</code>) steps in <code>PeiCore</code> function.</li>
<li>Please note that first PPI (PEIM to PEIM Interfaces) are installed together with some PPI Notifies, when PEI Core Service completes its initialization by calling <code>Initialize{SecurityServices,DispatcherData,ImageServices}</code>, as is indicated in debug.log.</li>
<li>We can continue to <code>PeiDipatcher</code>, which is responsible for discovering and loading PEIMs (PEI Modules). It is worth to step into this function and go through the code more carefully.
<ul>
<li><code>DiscoverPeimsAndOrderWithApriori</code> checks which PEIMs should be loaded before any other, which essentially determine the order of PEIMs.</li>
<li>Then dispatcher starts loading various PEIMs, starting with <code>PcdPeim</code>. Loading a PEIM may mean installation of additional PPIs and registration of associated Notifies.</li>
<li>The fourth PEIM is <code>PlatformPei</code> its logging is verbose because it handles: CMOS dumping, ACPI S3 detection and verification, various initialization related to memory and callbacks installation.</li>
</ul></li>
<li><code>PlatformPei</code> leads to temporary RAM migration, which changes the way we load debug symbols.</li>
<li>We should see log as follows:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>TemporaryRamMigration<span class="o">(</span>0x810000, 0x3F4E000, 0x10000<span class="o">)</span>
Install PPI: 3CD652B4-6D33-4DCE-89DB-83DF9766FCCA
Loading PEIM 52C05B14-0B98-496C-BC3B-04B50211D680
<span class="nv">PDB</span> <span class="o">=</span> /home/ost2/Desktop/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MdeModulePkg/Core/Pei/PeiMain/DEBUG/PeiCore.dll
Loading PEIM at 0x00007EE8000 <span class="nv">EntryPoint</span><span class="o">=</span>0x00007EEFF83 PeiCore.efi
<span class="o">(</span>...<span class="o">)</span>
</code></pre>
</div>
<ul>
<li>From previous analysis we know that <code>.text</code> section of <code>PeiCore</code> is <code>0x240</code> and <code>.data</code> is <code>0xaf40</code>, to apply changes in debugging session we should do as follows</li>
</ul>
<div class="codehilite">
<pre><span></span><code>Breakpoint <span class="m">6</span>, PeiCore <span class="o">(</span><span class="nv">SecCoreDataPtr</span><span class="o">=</span>SecCoreDataPtr@entry<span class="o">=</span>0x3f55d20, <span class="nv">PpiList</span><span class="o">=</span>PpiList@entry<span class="o">=</span>0x0, <span class="nv">Data</span><span class="o">=</span>Data@entry<span class="o">=</span>0x3f55628<span class="o">)</span> at /home/user/edk2/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c:169
<span class="o">(</span>gdb<span class="o">)</span> n
<span class="o">(</span>gdb<span class="o">)</span> si
<span class="o">(</span>gdb<span class="o">)</span> symbol-file Build/OvmfX64/DEBUG_GCC5/X64/PeiCore.debug
Load new symbol table from <span class="s2">"Build/OvmfX64/DEBUG_GCC5/X64/PeiCore.debug"</span>? <span class="o">(</span>y or n<span class="o">)</span> y
Reading symbols from Build/OvmfX64/DEBUG_GCC5/X64/PeiCore.debug...
<span class="o">(</span>gdb<span class="o">)</span> add-symbol-file Build/OvmfX64/DEBUG_GCC5/X64/PeiCore.debug <span class="o">(</span>0x00007EE8000+0x0000000000000240<span class="o">)</span> -s .data <span class="o">(</span>0x00007EE8000+0x000000000000af40<span class="o">)</span>
add symbol table from file <span class="s2">"Build/OvmfX64/DEBUG_GCC5/X64/PeiCore.debug"</span> at
.text_addr <span class="o">=</span> 0x7ee8240
.data_addr <span class="o">=</span> 0x7ef2f40
<span class="o">(</span>y or n<span class="o">)</span> y
Reading symbols from Build/OvmfX64/DEBUG_GCC5/X64/PeiCore.debug...
</code></pre>
</div>
<ul>
<li>To continue debugging we have to do the same for <code>DxeIpl</code></li>
</ul>
<pre><code>(gdb) symbol-file Build/OvmfX64/DEBUG_GCC5/X64/DxeIpl.debug
Load new symbol table from "Build/OvmfX64/DEBUG_GCC5/X64/DxeIpl.debug"? (y or n) y
Reading symbols from Build/OvmfX64/DEBUG_GCC5/X64/DxeIpl.debug...
(gdb) add-symbol-file Build/OvmfX64/DEBUG_GCC5/X64/DxeIpl.debug (0x00007EDE000+0x0000000000000240) -s .data (0x00007EDE000+0x0000000000004240)
add symbol table from file "Build/OvmfX64/DEBUG_GCC5/X64/DxeIpl.debug" at
.text_addr = 0x7ede240
.data_addr = 0x7ee2240
(y or n) y
</code></pre>
<ul>
<li>After that we are ready to start transition to DXE by using DXE IPL PPI (through <code>DxeIpl</code>, we can step to the point where <code>DXE IPL Entry</code>) string is printed in <code>debug.log</code> and then step into <code>TempPtr.DxeIpl->Entry</code> function</li>
<li>If everything was loaded correctly we should land in <code>DxeLoadCore</code>, where first boot mode is analyzed and appropriate actions are taken</li>
<li>Then <code>DxeLoadCore</code> look for DXE Core file and after loading it calls <code>HandOffToDxeCore</code> which prepare final switch to DXE.</li>
<li>Since switching to DXE is not so trivial to observe we will describe it in DXE related exercise.</li>
</ul>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@done+block@e2560cc7daa6477f918d4b266a29981a">
<div class="xblock xblock-public_view xblock-public_view-done" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="done" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@done+block@e2560cc7daa6477f918d4b266a29981a" data-request-token="980f71f4fef311eeabb30242ac12000b" 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-2" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@discussion+block@7a7906c18aaa499aba345956035af6a1">
<div class="xblock xblock-public_view xblock-public_view-discussion" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="discussion" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@discussion+block@7a7906c18aaa499aba345956035af6a1" data-request-token="980f71f4fef311eeabb30242ac12000b" 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+Arch4021_intro_UEFI+2023_v1" data-init="VerticalStudentView" data-runtime-class="LmsRuntime" data-runtime-version="1" data-block-type="vertical" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@vertical+block@2b74954893544c108aef03a60e89adb0" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@1af47530d9d54e0d935efe20c4c2381b">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@1af47530d9d54e0d935efe20c4c2381b" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><h2>Exercise #6: Welcome to DXE</h2>
<ul>
<li>Based on exercise #5 we are ready to jump into DXE phase</li>
<li>Let's start QEMU:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>qemu-system-x86_64 -nographic -bios Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd -chardev file,path<span class="o">=</span>debug.log,id<span class="o">=</span>edk2-debug -device isa-debugcon,iobase<span class="o">=</span>0x402,chardev<span class="o">=</span>edk2-debug -net none -s -S
</code></pre>
</div>
<ul>
<li>Let's start GDB and load symbols:</li>
</ul>
<div class="codehilite">
<pre><span></span><code>add-symbol-file Build/OvmfX64/DEBUG_GCC5/X64/PeiCore.debug <span class="o">(</span>0x00007EE8000+0x0000000000000240<span class="o">)</span> -s .data <span class="o">(</span>0x00007EE8000+0x000000000000af40<span class="o">)</span>
add-symbol-file Build/OvmfX64/DEBUG_GCC5/X64/DxeIpl.debug <span class="o">(</span>0x00007EDE000+0x0000000000000240<span class="o">)</span> -s .data <span class="o">(</span>0x00007EDE000+0x0000000000004240<span class="o">)</span>
add-symbol-file Build/OvmfX64/DEBUG_GCC5/X64/DxeCore.debug <span class="o">(</span>0x00007E9E000+0x0000000000000240<span class="o">)</span> -s .data <span class="o">(</span>0x00007E9E000+0x0000000000021e00<span class="o">)</span>
target remote :1234
</code></pre>
</div>
<ul>
<li>Following commands have to be executed manually.</li>
</ul>
<div class="codehilite">
<pre><span></span><code><span class="nb">break</span> PeiCore
c
<span class="nb">break</span> HandOffToDxeCore
c
</code></pre>
</div>
<ul>
<li>Interestingly second break point is not always set, when things happen too fast, sometimes GDB claims it does not know the symbol in following way:</li>
</ul>
<div class="codehilite">
<pre><span></span><code><span class="o">(</span>gdb<span class="o">)</span> <span class="nb">break</span> HandOffToDxeCore
Function <span class="s2">"HandOffToDxeCore"</span> not defined.
Make breakpoint pending on future shared library load? <span class="o">(</span>y or <span class="o">[</span>n<span class="o">])</span>
</code></pre>
</div>
<p>It probably means things happen to fast or GDB has some weird bug with looking for symbols, workaround that works for me most of the time is using Tab for symbol searching in between continue commands:</p>
<div class="codehilite">
<pre><span></span><code><span class="o">(</span>gdb<span class="o">)</span> <span class="nb">break</span> Pei<TAB>
PeiAllocatePages PeiDefaultMemRead8 PeiFfsFvPpiGetFileInfo PeiNotifyPpi
PeiAllocatePool PeiDefaultMemWrite PeiFfsFvPpiGetFileInfo2 PeiPcdLib.c
PeiCheckAndSwitchStack PeiDefaultMemWrite16 PeiFfsFvPpiGetVolumeInfo PeiReInstallPpi
PeiCore PeiDefaultMemWrite32 PeiFfsFvPpiProcessVolume PeiRegisterForShadow
PeiCoreEntry PeiDefaultMemWrite64 PeiFfsGetFileInfo PeiReportStatusCode
PeiCoreEntryPoint.c PeiDefaultMemWrite8 PeiFfsGetFileInfo2 PeiResetSystem
PeiCoreFvLocation.h PeiDefaultPciCfg2Modify PeiFfsGetVolumeInfo PeiResetSystem2
PeiCreateHob PeiDefaultPciCfg2Read PeiFreePages PeiServicesAllocatePages
PeiDefaultIoRead PeiDefaultPciCfg2Write PeiGetBootMode PeiServicesFfsFindSectionData3
PeiDefaultIoRead16 PeiDxeSmmCpuException.c PeiGetExtractGuidedSectionHandlerInfo PeiServicesFfsFindSectionData3.constprop.0
PeiDefaultIoRead32 PeiDxeVirtualMemory.c PeiGetHobList PeiServicesInstallPpi
PeiDefaultIoRead64 PeiDxeVmgExitVcHandler.c PeiImageRead PeiServicesLib.c
PeiDefaultIoRead8 PeiExtractGuidedSectionLib.c PeiInstallPeiMemory PeiServicesLocatePpi
PeiDefaultIoWrite PeiFfsFindFileByName PeiInstallPpi PeiServicesLocatePpi.constprop.0
PeiDefaultIoWrite16 PeiFfsFindNextFile PeiLoadImage PeiServicesNotifyPpi
PeiDefaultIoWrite32 PeiFfsFindNextVolume PeiLoadImage.constprop.0 PeiServicesReInstallPpi
PeiDefaultIoWrite64 PeiFfsFindSectionData PeiLoadImageLoadImage PeiServicesTablePointer.c
PeiDefaultIoWrite8 PeiFfsFindSectionData3 PeiLoadImageLoadImage.constprop.0 PeiSetBootMode
PeiDefaultMemRead PeiFfsFvPpiFindFileByName PeiLoadImageLoadImageWrapper PeimDispatchReadiness
PeiDefaultMemRead16 PeiFfsFvPpiFindFileByType PeiLocatePpi PeimEntryPoint.c
PeiDefaultMemRead32 PeiFfsFvPpiFindSectionByType PeiMain.c PeimEntryPoint.h
PeiDefaultMemRead64 PeiFfsFvPpiFindSectionByType2 PeiMain.h
<span class="o">(</span>gdb<span class="o">)</span> <span class="nb">break</span> PeiCore
Breakpoint <span class="m">1</span> at 0x7eee4fd: file /home/user/edk2/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c, line <span class="m">169</span>.
<span class="o">(</span>gdb<span class="o">)</span> c
Continuing.
Breakpoint <span class="m">1</span>, PeiCore <span class="o">(</span><span class="nv">SecCoreDataPtr</span><span class="o">=</span>0x3f55d20, <span class="nv">PpiList</span><span class="o">=</span>0x0, <span class="nv">Data</span><span class="o">=</span>0x3f55628<span class="o">)</span> at /home/user/edk2/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c:169
<span class="m">169</span> <span class="o">{</span>
<span class="o">(</span>gdb<span class="o">)</span> <span class="nb">break</span> Hand<TAB>
Handle.c HandoffInformationTable
<span class="o">(</span>gdb<span class="o">)</span> <span class="nb">break</span> HandOffToDxeCore
Breakpoint <span class="m">2</span> at 0x7ee05ce: file /home/user/edk2/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c, line <span class="m">450</span>.
<span class="o">(</span>gdb<span class="o">)</span> c
</code></pre>
</div>
<p>Please note above addresses could change, if you using different code base or different compilation parameters.</p>
<ul>
<li>Set breakpoint for <code>SwitchStack</code> function since stepping through <code>HandOffToDxeCore</code>, especially since areas dealing with page tables or CR3 breaks debugging sessions.</li>
</ul>
<div class="codehilite">
<pre><span></span><code><span class="o">(</span>gdb<span class="o">)</span> <span class="nb">break</span> SwitchStack
Breakpoint <span class="m">3</span> at 0x7edfd0e: SwitchStack. <span class="o">(</span><span class="m">2</span> locations<span class="o">)</span>
<span class="o">(</span>gdb<span class="o">)</span> c
Continuing.
Breakpoint <span class="m">3</span>, SwitchStack <span class="o">(</span><span class="nv">EntryPoint</span><span class="o">=</span>EntryPoint@entry<span class="o">=</span>0x7ea0ef0 <_ModuleEntryPoint>, <span class="nv">Context1</span><span class="o">=</span>Context1@entry<span class="o">=</span>0x3f56000, <span class="nv">Context2</span><span class="o">=</span>0x0, <span class="nv">NewStack</span><span class="o">=</span>NewStack@entry<span class="o">=</span>0x7e9dff0, <span class="nv">Context2</span><span class="o">=</span>0x0<span class="o">)</span>
at /home/user/edk2/MdePkg/Library/BaseLib/SwitchStack.c:42
<span class="o">(</span>gdb<span class="o">)</span>
</code></pre>
</div>
<ul>
<li>If we step into <code>SwitchStack</code> we will get to <code>InternalSwitchStack</code>, we have no symbols loaded for that function. You should load them (this is your challenge).</li>
<li><code>InternalSwitchStack</code> calls <code>_ModuleEntryPoint</code> defined in <code>DxeCoreEntryPoint.c:37</code> which works in a very similar way to PEI Core entry point.</li>
<li>Stepping in <code>_ModuleEntryPoint</code> should lead us to <code>DxeMain</code> for which the backtrace should look as follows:</li>
</ul>
<div class="codehilite">
<pre><span></span><code><span class="o">(</span>gdb<span class="o">)</span> bt
<span class="c1">#0 DxeMain (HobStart=0x3f56000) at /home/user/edk2/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c:236</span>
<span class="c1">#1 0x0000000007ea0f06 in ProcessModuleEntryPointList (HobStart=<optimized out>) at /home/user/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/AutoGen.c:507</span>
<span class="c1">#2 _ModuleEntryPoint (HobStart=<optimized out>) at /home/user/edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c:46</span>
<span class="c1">#3 0x0000000007ee10cf in InternalSwitchStack ()</span>
</code></pre>
</div>
<ul>
<li>DxeMain is the DXE phase entry point.</li>
</ul>
<h2>Exercise #7: DXE debug.log review</h2>
<ul>
<li>Let's check debug.log file:</li>
</ul>
<pre><code>PlatformPei: ClearCacheOnMpServicesAvailable
DiscoverPeimsAndOrderWithApriori(): Found 0x0 PEI FFS files in the 1th FV
DXE IPL Entry
Loading PEIM D6A2CB7F-6A18-4E2F-B43B-9920A733700A
PDB = /home/ost2/Desktop/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll
Loading PEIM at 0x00007E98000 EntryPoint=0x00007EAF2E5 DxeCore.efi
Loading DXE CORE at 0x00007E98000 EntryPoint=0x00007EAF2E5
Vector Hand-off Info PPI is gotten, GUIDed HOB is created!
AddressBits=36 5LevelPaging=0 1GPage=0
Pml5=1 Pml4=1 Pdp=64 TotalPage=66
Install PPI: 605EA650-C65C-42E1-BA80-91A52AB618C6
Notify: PPI Guid: 605EA650-C65C-42E1-BA80-91A52AB618C6, Peim notify entry point: 82E669
Debug Timer: FSB Clock = 200000000
Debug Timer: Divisor = 2
Debug Timer: Frequency = 100000000
Debug Timer: InitialCount = 10000000
CoreInitializeMemoryServices:
BaseAddress - 0x3F59000 Length - 0x3CA7000 MinimalMemorySizeNeeded - 0x320000
</code></pre>
<ul>
<li>As we can see the first DXE related log happens a little bit earlier than switching between phases. So we can note that EDKII does not indicate places where we change phases.</li>
<li>DXE phase is quite verbose and big in terms of executed code, so we will just get through its most important parts, as you can see above we started with initialization of memory related services.</li>
<li>Then DXE proceed with initialization of other services and table, but does it quitely.</li>
<li>After that DXE retreive from HOBs information deliverd by PEI phase:</li>
<li>First are information about memory allocations, show memory type and adresses.</li>
</ul>
<pre><code>(...)
Memory Allocation 0x00000004 0x7C00000 - 0x7DFFFFF
Memory Allocation 0x00000007 0x7E00000 - 0x7E7DFFF
Memory Allocation 0x00000004 0x3F36000 - 0x3F55FFF
</code></pre>
<ul>
<li>Second Firmware Volume information:</li>
</ul>
<pre><code>FV Hob 0x900000 - 0x14FFFFF
</code></pre>
<ul>
<li>And then it proceeds with architectural protocols installation</li>
</ul>
<pre><code>InstallProtocolInterface: D8117CFE-94A6-11D4-9A3A-0090273FC14D 7EC0F10
(...)
</code></pre>
<ul>
<li>Finally DXE puts the main actor on stage, namely the DXE dispatcher, responsible for loading DXE drivers, by calling the <code>CoreDispatcher</code> function. Each driver has its own entry point which performs some action. For OVMF X64 95 drivers are loaded:</li>
</ul>
<pre><code>grep "Loading driver at" debug.log
(...)
Loading driver at 0x00006CF6000 EntryPoint=0x00006CFC735 UefiPxeBcDxe.efi
Loading driver at 0x00006CB8000 EntryPoint=0x00006CBF808 IScsiDxe.efi
Loading driver at 0x00006D20000 EntryPoint=0x00006D23B7C VirtioNetDxe.efi
Loading driver at 0x00006CE8000 EntryPoint=0x00006CED1EE UhciDxe.efi
Loading driver at 0x00006CAF000 EntryPoint=0x00006CB533A EhciDxe.efi
Loading driver at 0x00006CA2000 EntryPoint=0x00006CAB912 XhciDxe.efi
Loading driver at 0x00006C98000 EntryPoint=0x00006C9E6D6 UsbBusDxe.efi
Loading driver at 0x00006CE1000 EntryPoint=0x00006CE5112 UsbKbDxe.efi
Loading driver at 0x00006D1A000 EntryPoint=0x00006D1DC76 UsbMassStorageDxe.efi
Loading driver at 0x00006CDA000 EntryPoint=0x00006CDDD91 QemuVideoDxe.efi
Loading driver at 0x00006CEF000 EntryPoint=0x00006CF2C3C VirtioGpuDxe.efi
</code></pre>
<ul>
<li>After the DXE dispatcher, some minor cleanup is performed and the BDS phase entry is called.</li>
</ul>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@done+block@a3de1effd7624a28b7cc57125c05adf6">
<div class="xblock xblock-public_view xblock-public_view-done" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="done" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@done+block@a3de1effd7624a28b7cc57125c05adf6" data-request-token="980f71f4fef311eeabb30242ac12000b" 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-2" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@discussion+block@5477c00fe16b4dd08a3f9462aa142cbf">
<div class="xblock xblock-public_view xblock-public_view-discussion" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="discussion" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@discussion+block@5477c00fe16b4dd08a3f9462aa142cbf" data-request-token="980f71f4fef311eeabb30242ac12000b" 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+Arch4021_intro_UEFI+2023_v1" data-init="VerticalStudentView" data-runtime-class="LmsRuntime" data-runtime-version="1" data-block-type="vertical" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@vertical+block@31cb3cb2c18a4aa1a06cd108f0d1493a" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="vert-mod">
<div class="vert vert-0" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@cb4c5f50170142e48295dd63964c5bff">
<div class="xblock xblock-public_view xblock-public_view-markdown" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="markdown" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@markdown+block@cb4c5f50170142e48295dd63964c5bff" data-request-token="980f71f4fef311eeabb30242ac12000b" data-graded="True" data-has-score="False">
<div class="markdown_xblock"><h2>Exercise #10: Welcome in BDS</h2>
<ul>
<li>Based on exercise #9 we are redy to jump into BDS phase.</li>
<li>Please try to perform step in (<code>s</code>) transition from DXE to BDS by adding the symbols mentioned below.</li>
<li>Let's start QEMU:</li>
</ul>
<pre><code>qemu-system-x86_64 -nographic -bios Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd -chardev file,path=debug.log,id=edk2-debug -device isa-debugcon,iobase=0x402,chardev=edk2-debug -net none -s -S
</code></pre>
<ul>
<li>Let's start debugging BDS:</li>
</ul>
<pre><code>add-symbol-file Build/OvmfX64/DEBUG_GCC5/X64/BdsDxe.debug (0x00007062000+0x0000000000000240) -s .data (0x00007062000+0x000000000001a080)
target remote :1234
break BdsEntry
c
</code></pre>
<ul>
<li>We are in BDS.</li>
</ul>
<h2>Exercise #10: Welcome in BDS</h2>
<ul>
<li>Quckily looking at the <code>BdsEntry</code> (<code>MdeModulePkg/Universal/BdsDxe/BdsEntry.c</code>) function, we see that the log output from the first exercise, <code>[Bds] Entry...</code>, is first thing BDS does.</li>
<li>BDS quietly deals with all actions related to variables validation and loading the variable policy protocol:</li>
</ul>
<pre><code>[BdsDxe] Locate Variable Policy protocol - Success
</code></pre>
<ul>
<li>Then BDS deal with locales (languages) by initializing the setup menu language accordingly:</li>
</ul>
<pre><code>Variable Driver Auto Update Lang, Lang:eng, PlatformLang:en Status: Success
</code></pre>
<ul>
<li>Then, since BDS would like to show something to user it tries to use the console, which triggers PCI scanning:</li>
</ul>
<pre><code>PlatformBootManagerBeforeConsole
Registered NotifyDevPath Event
PCI Bus First Scanning
PciBus: Discovered PCI @ [00|00|00]
PciBus: Discovered PCI @ [00|01|00]
PciBus: Discovered PCI @ [00|01|01]
BAR[4]: Type = Io32; Alignment = 0xF; Length = 0x10; Offset = 0x20
PciBus: Discovered PCI @ [00|01|03]
PciBus: Discovered PCI @ [00|02|00]
BAR[0]: Type = PMem32; Alignment = 0xFFFFFF; Length = 0x1000000; Offset = 0x10
BAR[2]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x18
(...)
</code></pre>
<ul>
<li>Scanning triggers various drivers (e.g. <code>QemuVideo</code>), protocols installations, and security checks <code>[Security]</code>. This is mostly preparation for potential user interaction in the following steps.</li>
<li>Next, hot keys are registered, to support entering the setup or quick boot menu:</li>
</ul>
<pre><code>[Bds]RegisterKeyNotify: 000C/0000 80000000/00 Success
[Bds]RegisterKeyNotify: 0017/0000 80000000/00 Success
[Bds]RegisterKeyNotify: 0000/000D 80000000/00 Success
</code></pre>
<ul>
<li>Then BDS connects all the default consoles, which means on outputs detected earlier, to whichever drivers were found. You can find out something happened since our terminal where we are running QEMU changed color.</li>
<li>Finally BDS informs us about OS-indicated features, and dumps various information related to the boot process:</li>
</ul>
<pre><code>[Bds]OsIndication: 0000000000000000
[Bds]=============Begin Load Options Dumping ...=============
Driver Options:
SysPrep Options:
Boot Options:
Boot0000: UiApp 0x0109
Boot0001: UEFI QEMU DVD-ROM QM00003 0x0001
Boot0002: UEFI PXEv4 (MAC:525400123456) 0x0001
Boot0003: EFI Internal Shell 0x0001
PlatformRecovery Options:
PlatformRecovery0000: Default PlatformRecovery 0x0001
[Bds]=============End Load Options Dumping=============
</code></pre>
<ul>
<li>Now BDS waits for user interaction. E.g. entering setup or quick boot menu. If no action is taken, boot options would be executed according to priority.</li>
<li>On the screen we can find:</li>
</ul>
<pre><code>BdsDxe: failed to load Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0): Not Found
</code></pre>
<p>This is quite normal assuming we didn't connect a DVD-ROM to QEMU. <br />
* Then if we hadn't given the <code>-net none</code> option we would see the PXE loading screen. And as a final step we land in the UEFI Shell since no options was selected:</p>
<pre><code>UEFI Interactive Shell v2.2 EDK II UEFI v2.70 (EDK II, 0x00010000) Mapping table BLK0: Alias(s): PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) Press ESC in 1 seconds to skip startup.nsh or any other key to continue. Shell>
</code></pre>
</div>
</div>
</div>
<div class="vert vert-1" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@done+block@67cf8f9a722a4b0f89631a68e8db31da">
<div class="xblock xblock-public_view xblock-public_view-done" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="done" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@done+block@67cf8f9a722a4b0f89631a68e8db31da" data-request-token="980f71f4fef311eeabb30242ac12000b" 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-2" data-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@discussion+block@f2c20e75ad79481c9d48ded0e8fb8617">
<div class="xblock xblock-public_view xblock-public_view-discussion" data-course-id="course-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1" data-block-type="discussion" data-usage-id="block-v1:OpenSecurityTraining2+Arch4021_intro_UEFI+2023_v1+type@discussion+block@f2c20e75ad79481c9d48ded0e8fb8617" data-request-token="980f71f4fef311eeabb30242ac12000b" 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>