Search code examples
linuxmacoskernelbootefi

Passing kernel parametes to EFI-Stub in Apple's EFI env


Good day, everybody. I'm trying to shorten the boot process of an iMac dual-booting OS-X and Ubuntu as much as possible. So far i managed to boot grub (and Ubuntu afterwards) directly by Apple's EFI boot manager. I've accomplished this by masquerading (via hardlinks, alias, folder's tree, etc.) the grub binaries as what Apple's firmware expects for booting OsX itself. (Example:

$>sudo ln EFI/ubuntu/grubx64.efi System/Library/CoreServices/boot.efi

)
Now i'm trying to go a step further, that is, eliminating GRUB. I know that modern Linux distros' do have EFI stubs incorporated in the kernel, so that, in principle, one could boot directly into the kernel (via EFI/UEFI firmware) without the need of a (secondary) boot manager, such as GRUB2, for instance. (Like this:

$>sudo ln vmlinuz System/Library/CoreSerivces/boot.efi

) The problem with Apple is it's "peculiar" EFI implementation. In order for the Linux kernel's EFI stub to work, one must be able to pass parameters to it (root path, initial ram disk, etc.) Well, this is easily accomplished using secondary boot managers (GRUB, rEFInd, ELILO, etc. They do pass a command line string to the EFI binary) but this is exactly what i'd like to bypass. Is there a way to pass parameters to an arbitrary EFI binary, loaded by Apple's EFI firmware? (I've tried with the com.apple.Boot.plist but to no avail.) Or, alternatively, is there some way to pass parameters to the linux kernel during the boot process WITHOUT the commandline (maybe via some text file)?


Solution

  • Bingo!!!! Apple's EFI is working and the solution is simpler than expected. No need for complicated folder hierarchies. Simply create a small HFS+ partition, copy the linux kernel efi stub (e.g. vmlinuz-3.13.0-46-generic.efi.signed) in it, renaming the file so that it ends with .efi (Apple's EFI refuses to start anything that doesn't end with .efi extension) like vmlinuz.efi, copy the initial ram disk too (e.g. initrd.img-3.13.0-46-generic), possibly renaming it to something simpler like initrd.img, then use efibootmgr to create a new boot entry like this (assuming X is the harddrive where you created the HFS+ partiotion and Y is the number of the partition itself):

    efibootmgr -d /dev/sdX -p Y -c -L "Ubuntu (EFI-Stub)" -l /vmlinuz.efi -u "root=UUID=b0c4efb9-95b0-4e5d-98e1-8beb43f413c2 ro rootflags=subvol=@  quiet splash initrd=\initrd.img"
    

    Optionally you can also create an icon and a label that will show-up when you power up the system while holding the "alt" key. It is working great and it is also worth the effort. The display driver gets configured DIRECTLY by EFI and shows details NOT visible if booting via GRUB!!!

    UPDATE

    With Ubuntu version up to 16.10 somehow things didn't work anymore. X couldn't detect the KMS settings so that it failed on start up. Luckily, with Ubuntu 17.04, things are working again. As for the Icon showing up in the built-in boot manager, do as follow:

    1) Boot into OSX.

    2) Mount the HFS+ partition where our Linux boot loader (in our example, vmlinuz.efi) resides in whichever manner you prefer.

    3) Grab from the web an Ubuntu Logo in .icns format (caution, its size must not exceed 512x512 px) and put it in the very same folder where our boot loader is located. It must be named .VolumeIcon.icns

    4) bless the boot loader like this:

    sudo bless --folder /Volumes/<MyBootPartitionMountPoint> --file /Volumes/<MyBootPartitionMountPoint>/vmlinuz.efi --label 'Ubuntu 17.10' 
    

    Finished.

    Now, holding down the alt key while powering up the machine will kick start the built-in EFI boot manager, with a nice Ubuntu Logo next to the Apple.

    Two last things.

    1) The process of setting up an Icon for the built-in boot manager is really optional. Not much use of it. Actually, if you try to boot Ubuntu by clicking on the Ubuntu icon in the boot manager screen, the relevant EFI boot vars will NOT be read, so Linux won't startup. It's pretty Eye Candy only.

    2) Important: Don't forget to replace the root=UUID=blahblah with the real UUID of your / Linux partition. This one in the sample code is just an example.

    Enjoy