Saturday, December 29, 2012

More on EFI...

Considering it has been awhile since my last post, I figured I'd write a post to discuss the current status of my tool, Mac Linux USB Loader. The tool essentially copies an EFI binary to the USB stick which boots Linux from the ISO. How simple. In theory, I suppose, yes. In reality? Whole other ballgame.

Perhaps it would be worthwhile to discuss exactly what EFI applications are composed of. EFI programs are very special in that the operating system never executes them. They are run by the computer's firmware itself, independent of the operating system, which effectively makes them truly platform-independent programs. Platform independent programs have existed before; they can be created in Java or C#/Mono. From a technical standpoint, EFI programs are also different from traditional programs in the sense that they must be compiled using a cross-compiler, as no native development tools exist for EFI. This is understandable, considering EFI is firmware: it runs before the operating system, and EFI services are often terminated by the OS upon completion of the boot process.

Therefore, development of EFI programs is exponentially more difficult. First off, EFI programs are written in C, and you cannot rely on any of C's standard libraries to help you. If it's not in the EFI libraries, you either need to write it yourself or find an equivalent function that is already implemented.


// hello.c

#include
#include

EFI_STATUS
efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
{
    InitializeLib(image_handle, systab);
    
    Print(L"Hello, EFI!\n");
    Print(L"You have a working EFI shell.\n");
    
    return EFI_SUCCESS;
}


As you can see from the above example program that I wrote, printing output using printf() is not possible. You have to use a function in the EFI libraries provided by gnu-efi, a EFI toolkit available for POSIX platforms (Mac, Linux, et al) that does the job of TianoCore, the official EFI toolkit that is only available for Windows.

So, why does the firmware for Mac Linux USB Loader need to be implemented in EFI? Simple. OS X's boot manager, accessed by pressing the option/alt key after the boot chimes, only detects EFI programs that are on external drives at the special path* of /EFI/BOOT/BOOT.EFI. So  on a machine with 64-bit firmware (all recent Macs), that file needs to be called BOOTX64.EFI.  And because OS X is not loaded, whatever program is there needs to be written in EFI.

Operating system loaders are not the only programs written in EFI. Oh no. There are EFI shells, which are like bash on a UNIX machine, except they can execute EFI programs like the one above.

More on EFI coming up soon. Happy new year, all (except to you folks not using the Gregorian calendar ;) ).

* - Well, not entirely. A file can be "blessed" with the ability to boot. OS X's boot loader does this, as it is located at /System/Library/CoreServices/boot.efi, which is not located in that special path. But I'm not discussing this further.

Monday, December 3, 2012

A Method to Boot Linux from Flash Drives via EFI on Macs and Why I Hate the EFI Support in Linux

Linux and Macs are like estranged cousins who are always a little antsy around each other. While they can trained to play together, deep down there is a deep resentment of each other. This relationship is not inherently by fault of either Linux or Apple; rather, the issues seem to lie with the hardware and firmware on Mac computers.

Sadly, the situation does not look like it will fix itself anytime soon. Macs require booting via EFI, which for all intents and purposes is horrible on the Linux platform. The only real way to boot Linux via EFI is unfortunately by hacks: GRUB 2, the rudimentary and ubiquitous Linux boot loader used on practically every installation, has working but poor EFI support, and other software like ELILO is not much better.

EFI is going to be way more common now than it was in the past largely due to Microsoft's decision to require UEFI firmware on all new PCs shipping as Windows 8 certified. So the Linux community finds it necessary to get a working EFI boot solution going quickly, but, as the video below demonstrates, everything is not all roses and unicorns:


So, what is to be done with PCs (and Macs) that are now booting via EFI? Well, I have one solution for   a common issue faced by Mac users: booting a Linux distribution from a USB drive without using rEFIt or rEFInd. Fedora seems to have something going, as shown by the following video below, which demonstrates Fedora booting natively on a Mac via EFI:

Sadly, Ubuntu and its derivatives do not have any native or supported way to boot via EFI on Mac platforms. So, I have created a tool called Mac Linux USB Loader to do just that! Open source (license pending) and on GitHub, Mac Linux USB Loader is a free application that copies a selected Linux distribution's ISO file and copy it and an EFI boot loader to the thumb drive of your choice. Best yet, it is non-destructive, which means that unlike other tools, you do not have to erase your thumb drive: all your data is preserved and untouched.

The tool has been successfully used to boot Linux Mint 14.1 from a 2 GB thumb drive. In theory, this shouldn't be restricted to Ubuntu; the only real requirement is that the distribution supports loopback. If you want to try the tool, fork the repository on GitHub and then compile the code in Xcode (binary releases will be released when the code is cleaned up a bit). Please note that the tool is in beta, is buggy, and may not work. You have no warned.

Give it a try and leave your comments/questions/thoughts in the comments below.