UEFI ISO Bare Bones: Difference between revisions
[unchecked revision] | [unchecked revision] |
(Added section on creating a FAT image within the ISO image) |
No edit summary |
||
Line 1: | Line 1: | ||
{{BeginnersWarning}} |
|||
{{Rating|2}} |
{{Rating|2}} |
||
Revision as of 03:45, 10 September 2018
Difficulty level |
---|
Medium |
In this tutorial we will create an ISO image containing a bare bones UEFI application for the 32-bit x86 platform.
You are recommended to have read and fully understood the Bare Bones tutorial first. The UEFI page provides some background to the UEFI boot process and should also be consulted first.
Prerequisites
You will need a GCC Cross-Compiler targeting the i686-pc-mingw32 target, and the gnu-efi package. Extract gnu-efi somewhere on your system (you will need to access its 'inc' directory). We use xorriso to create the iso image. You will also need an emulator to test on (this tutorial was tested with VirtualBox - ensure the EFI option is selected in the VM options).
You will also need some way of creating a FAT filesystem image (e.g. with the Loopback Device or MTools)
hello.c
Create a file with the following:
#include <efi.h>
#include <efilib.h>
EFI_SYSTEM_TABLE *gST;
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS Status;
EFI_INPUT_KEY Key;
/* Store the system table for future use in other functions */
gST = SystemTable;
/* Say hi */
Status = gST->ConOut->OutputString(gST->ConOut, L"Hello World\n\r");
if (EFI_ERROR(Status))
return Status;
/* Now wait for a keystroke before continuing, otherwise your
message will flash off the screen before you see it.
First, we need to empty the console input buffer to flush
out any keystrokes entered before this point */
Status = gST->ConIn->Reset(gST->ConIn, FALSE);
if (EFI_ERROR(Status))
return Status;
/* Now wait until a key becomes available. This is a simple
polling implementation. You could try and use the WaitForKey
event instead if you like */
while ((Status = gST->ConIn->ReadKeyStroke(gST->ConIn, &Key)) == EFI_NOT_READY) ;
return Status;
}
Building
To build, we use our cross-compiler:
i686-pc-mingw32-gcc -c -o hello.o -Ipath/to/gnu-efi/inc -Ipath/to/gnu-efi/inc/ia32 hello.c
i686-pc-mingw32-ld -b pei-i386 -shared -dll --subsystem 10 -nostdlib -o hello.efi -e _efi_main hello.o
Note here that '--subsystem 10' specifies an EFI application.
Creating the FAT image
Next, you will need to create a FAT filesystem image. How to do this is beyond the scope of this tutorial (as it greatly depends on the tools you are using) but it needs to contain your hello.efi file located at /EFI/BOOT/BOOTIA32.EFI
We will assume your FAT image is called hello.img
Creating the ISO
The iso image is a standard ISO9660 image which contains our FAT image as a file. A special El Torito option then points EFI aware systems to this image to be loaded.
mkdir iso
cp hello.img iso
xorriso -as mkisofs -R -f -e hello.img -no-emul-boot -o efi.iso iso
The efi.iso file should now be directly bootable in VirtualBox (assuming you have ticked the EFI option in the settings for your VM).
What to do next?
You may want to try using some more of the EFI boot services, e.g. to read more files from your iso image, manage memory etc (see the UEFI Specifications page for further documentation of this). You may also want to look at creating a 64-bit UEFI application instead. Finally, you could consider trying to create a CD that boots under normal PC BIOS and UEFI (possibly both 32- and 64-bit).