Shaun ONeil

Creating a grub-efi bootstick for OSX

Work in progress, but I'm getting somewhere

Started off by building a fresh x86_64 VM of Ubuntu 11.04 to work in. Building a fresh grub2 is easy enough:

$ sudo apt-get install build-essential bison m4 flex libdevmapper-dev
$ wget ftp://ftp.gnu.org/gnu/grub/grub-1.99.tar.gz
$ tar xzf grub-1.99.tar.gz
$ cd grub-1.99
$ ./configure --with-platform=efi --enable-grub-mkfont=no --disable-nls --enable-efiemu=no

After a convincing looking build, I find all my modules are looking pretty in grub-core, so I should be good to go.

I'm still working thru which modules I actually require, but so far, I have:

  • normal: core functionality
  • boot: really freaking handy
  • help: handy while I figure out all the new jazz in grub2
  • search
  • search_label
  • search_fs_uuid
  • search_fs_file: search functionality is really handy when you don't know what device you're on
  • configfile: being able to load in a new configfile without rebuilding grub is very useful
  • tar: was handy for memdisk support
  • loopback: as I want to be able to boot loopback isos from grub
  • elf: for linux support
  • chain: for legacy booting
  • iorw: peek & poke for efi addresses (more on this later)
  • partitions
    • part_gpt: guid partitions (for mac booting)
    • part_msdos: msdos partitions (for legacy booting)
    • part_bsd: just in case. They're out there.
  • filesystems
    • fat: because I'll likely be using it for my stick
    • hfs: just in case
    • hfsplus: for mac booting
    • iso9660: for iso loopback booting
    • ext2: for linux booting
  • frontend: still working on this bit.
    • terminal
    • video
    • videotest
    • videoinfo
    • font
    • gfxterm
    • gfxmenu
    • jpeg
    • png

phew!

So the next job, is to write an initial config file for grub, else it starts .. and does nothing else.

I've gone nice & simple here; I just want to find a 'proper' config and use that, as it's much easier to fiddle with on the fileystem.

static.cfg:

search --set -f /bootstick/grub/grub.cfg root
if [ -e /bootstick/grub/grub.cfg ]; then
    set prefix=($root)/bootstick/grub
    load_video
    configfile /bootstick/grub/grub.cfg
else
    echo "E: Could not find root device!"
fi

So, the search line looks for /bootstick/grub/grub.cfg, and if it finds it, sets $root to that device it found it on. This should be all the magic we need to start booting from the bootstick without knowing what device it is in advance.

The rest should be pretty obvious, bash-style; we use the device we just found as grub's prefix device (so we can find modules on the filesystem), and load a new configfile from it.

Then, we start rolling this together:

./grub-mkimage \ 
 --directory=grub-core/ \ 
 --prefix=/bootstick/grub/ \ 
 --config=static.cfg \ 
 --output=bootx64.efi \ 
 --format=x86_64-efi \
normal boot help search search_label search_fs_uuid search_fs_file \
configfile tar loopback elf chain iorw  part_gpt part_msdos part_bsd \
fat hfs hfsplus iso9660 ext terminal video videotest videoinfo font \
gfxterm gfxmenu jpeg png

So, we're using the modules from grub-core, using the config we just made, and I want an x86_64 target. The rest is just a list the modules I want built-in.