<h1class="post-title">UEFI Development On x86 With EDK2</h1>
<timedatetime="21-04-18"class="post-date">Sunday, April 18 2021</time>
</header>
<hr>
<p>I made this blog so I could remember how to do stuff that had instructions spread around the internet.
So here is how I setup my environment for developing EFI applications.</p>
<h2id="requirements">Requirements</h2>
<p>On Artix or other Arch-based distros like Manjaro I installed the following packages: <codeclass="language-plaintext highlighter-rouge">gcc nasm iasl</code></p>
<p>Here is what the packages do:</p>
<ul>
<li>GCC is obviously the GNU Compiler Collection and it allows us to compile C code to machine code.</li>
<li>NASM stands for Netwide Assembler. It is an assembler and disassembler for 32 and 64 bit Intel x86 platforms.</li>
<li>IASL stands for the ACPI Source Language Compiler/Decompiler. This will compile any ACPI calls to our local machine’s code.</li>
</ul>
<p>We need all these packages to start our (U)EFI journey.
Now that these are installed, let’s setup our environment.</p>
<h2id="building-edk2">Building EDK2</h2>
<p>I used the stable/202011 branch as that is latest stable version of the EDK2 project.</p>
<p>Notice we source a file with <codeclass="language-plaintext highlighter-rouge">.</code> before continuing. This is needed to load some tools and options into our shell for later. The environment variable <codeclass="language-plaintext highlighter-rouge">EDK_TOOLS_PATH</code> is set so that EDK knows where to find itself later. Now that everything is loaded up, we can modify a config file located at <codeclass="language-plaintext highlighter-rouge">Conf/target.txt</code>.</p>
<p>The most important options are these, feel free to append them to the end of the file; there is no default value for them.</p>
<p>There are other options, but I don’t know about them much, so I’m just sticking with this for now.</p>
<p>Finally, after all this work, we can build some .efi files. Let’s compile the <codeclass="language-plaintext highlighter-rouge">Helloworld.efi</code> file!
Simply run the <codeclass="language-plaintext highlighter-rouge">build</code> command in the terminal.
You can find your compiled EFI files by running this <codeclass="language-plaintext highlighter-rouge">ls</code> command:</p>
<p>This will show all HelloWorld.efi files for all architectures and toolchains (if you decide to change them).</p>
<h2id="running-in-uefi-shell">Running In UEFI Shell</h2>
<p>Once all this is complete, you will want to run your EFI files.
To do so, let’s first add an EFI shell to use at boot.
This will appear as an option in your bootloader, like GRUB, which is what I will show documentation for in this article.</p>
<p>So, first thing is first,
<ahref="https://github.com/tianocore/edk2/blob/UDK2018/ShellBinPkg/UefiShell/X64/Shell.efi?raw=true">download and EFI shell file</a>.
Second, move it to a partition (FAT formatted) which can be used for the UEFI.
On my Linux system, this is /boot. On others there may be no FAT filesystem so attach a USB and format it as FAT.
Third, add the <codeclass="language-plaintext highlighter-rouge">EFI Shell</code> option to your grub boot file.
Substitute hdX with the right hard drive (I did it with trial and error) as when it doesn’t work I would hit ‘e’ on grub and add the <codeclass="language-plaintext highlighter-rouge">ls</code> GRUB command.
Substitute the gptX with the correct partition, or msdosX if it is a DOS formatted partition table.
My <codeclass="language-plaintext highlighter-rouge">Shell.efi</code> was placed in /boot/EFI/.</p>
<p>When we run our <codeclass="language-plaintext highlighter-rouge">ls</code> command from earlier, remember we saw our <codeclass="language-plaintext highlighter-rouge">HelloWorld.efi</code> file.
Let’s move this file somewhere useful, like for me, <codeclass="language-plaintext highlighter-rouge">/boot</code>.
Then, once we’re in our UEFI shell we can run commands:</p>