UEFI ISO Bare Bones: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
(Created page)
 
m (fix ld options)
Line 51: Line 51:
To build, we use our cross-compiler:
To build, we use our cross-compiler:
<source lang="bash">i686-pc-mingw32-gcc -c -o hello.o -Ipath/to/gnu-efi/inc -Ipath/to/gnu-efi/inc/ia32 hello.c
<source lang="bash">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 hello.o</source>Note here that '--subsystem 10' specifies an EFI application.
i686-pc-mingw32-ld -b pei-i386 -shared -dll --subsystem 10 -nostdlib -o hello.efi -e _efi_main hello.o</source>Note here that '--subsystem 10' specifies an EFI application.


== Creating the ISO ==
== Creating the ISO ==

Revision as of 23:04, 8 February 2014

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).

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 ISO

We need a directory for the contents of our image. Note that the special file 'EFI/BOOT/BOOTIA32.EFI' is used to automatically boot x86 UEFI applications.

mkdir -p iso/EFI/BOOT/BOOTIA32.EFI
cp hello.efi iso/EFI/BOOT/BOOTIA32.EFI
xorriso -as mkisofs -R -f -e EFI/BOOT/BOOTIA32.EFI -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).

See also

UEFI