1. Understanding which UEFI protocols to use, fortunately these are well documented in the UEFI specification. Unfortunately the specification is a couple of thousand pages long, so be prepared to spend some time working out how it all hangs together.
2. Figuring out how to call the protocols using the GNU EFI wrapper shim.
3. Generating a UEFI PE COFF image using some objcopy runes.
So, the best way to start was to write a "Hello World" program and to work up from there. First, I installed the gnu-efi development library using:
sudo apt-get install gnu-efi
Next I hacked up the classic "Hello World", this can be found here. Then considerable amount of Googling was required to figure out how to use objcopy to help create the desired executable image. The Makefile containing these runes can be found here.
So what next? Well, this little adventure is my first step in a quest to write a bunch of tests so ensure UEFI firmware has functional protocols to allow grub to load a kernel. I was hoping to re-use the firmware test suite framework but it may take some effort since I don't have any POSIX support on UEFI, so I'm going to have to scope out how much effort is required to port the framework to UEFI.
Anyhow, it's a start.