Okay, here follows now a somewhat more complex topic. I want to ask what's the simplest way to implement a clean EFISTUB Linux kernel booting through the rEFInd boot manager?
The very best method would be a Linux distro which natively includes an install option for EFISTUB via rEFInd. Unfortunately this doesn't exist. Even the rEFInd supporting Manjaro Linux installer is using for booting the Linux kernel a grubx64.efi file (which is loaded by rEFInd). That really doesn't make a lot of sense. (It effectively makes absolutely no sense.)
Well, in a lot of cases, native EFI booting via GRUB is working fine also for Apple hardware. However, there are some situations where that is not possible. I am thinking in particular of all the Apple models which doesn't continuously expose the video BIOS in native EFI mode. For example, this is true for all non-MXM based (earlier & later) models which doesn't contain an Intel GPU but still have a separate GPU chip. On such Apple hardware, the video BIOS is embedded in the main EFI firmware and not in a separate flash chip (like at the MXM GPU cards). Addition: It turns out that this problem is also present at certain Apple MXM GPU cards.
While the vBIOS information is in legacy CSM BIOS emulation mode (aka Apple boot camp) always present and accessible, it is NOT under native EFI. So, when Linux is booting in EFI over GRUB the kernel is unable to reach the vBIOS information and cannot proceed with KMS (kernel mode-setting). On Radeon GPU based systems this results in an *Error* No UMS support in Radeon module!
message. Source: Linux issues on iMac11,2
Confirmed (incomplete) list of Apple models affected by "vBIOS not exposed in EFI":
- iMac4,1 & iMac5,1 (Radeon X1600)
- Macmini4,1 (GeForce 320M)
- iMac11,2 (Radeon HD 4670)
The solution for this problem is to boot the bare Linux kernel directly from rEFInd. This allows the Linux kernel to reach the necessary vBIOS information and initialize the kernel mode-setting properly. If someone needs to install just the bare Linux kernel booting via rEFInd please check the section "Optional further steps" at the end.
So far, my intended steps are:
Prepare the desired partitioning layout under Mac OS. In my case this would be: sda1 (EFI ESP), sda2 (Macintosh HD), sda3 (Apple Recovery HD), sda4 (Linux HD) Note, the Recovery Partition is not visible in the Apple disk utility.
Install Ubuntu through CSM BIOS emulation (with MBR) on partition sda4. (No additional boot, swap or data partition is used in this example.) Important note, the steps 1 to 3 mentioned below must be carried out before a reboot is made.
After Ubuntu is installed and the EFI adjustments are in place, install rEFInd directly from the CD/DVD. This option is avaiable in newer rEFInd builds. Download the corresponding image from the official website, burn it to a CD/DVD, boot from it and chose the "install" option.
This topic becomes even more complicated because of Apple specific EFI restrictions. At a regular UEFI environment, the steps described here How to boot load the kernel using EFI stub (efistub) loader? (See the SECOND answer) would allow a migration to EFISTUB kernel booting.
However, Apple EFI firmware based systems requires some additional modifications. A further limitation is that Linux runs during the first phase in CSM BIOS mode. As a consequence, the step "Add the boot entry" (with efibootmgr) cannot be applied. This must be done later over the EFI Shell (outside of Linux).
The following steps describe how a regular EFISTUB booting from the stock Apple EFI firmware is established.
When Ubuntu is completely installed, mount the efi esp partition at
/boot/esp
. (Be aware, a regular EFI booting Ubuntu installation uses a mounting point in/boot/efi
. So the following commands must be adjusted if the mount point differs.) Because Ubuntu was in our case installed via CSM BIOS emulation, theubuntu
directory is missing on the ESP. It has to be created first:mkdir /boot/esp/EFI/ubuntu
Create a new file
sudo nano /etc/kernel/postinst.d/zz-update-efistub
with the following contents:#!/bin/sh rm /boot/esp/EFI/ubuntu/* cp /vmlinuz /vmlinuz.efi cp /vmlinuz* /initrd.img /boot/esp/EFI/ubuntu/ rm /boot/esp/EFI/ubuntu/vmlinuz.old
This is called a hook. It will sync the ESP kernel-related files to those at the root partition. Make it executable with:
sudo chmod +x /etc/kernel/postinst.d/zz-update-efistub sudo /etc/kernel/postinst.d/zz-update-efistub
The
vmlinuz.efi
kernel loader is needed at older Apple EFI firmware versions. On those the normalvmlinuz
file is not recognized as bootable.As mentioned, the boot entry cannot be established because Linux is not in UEFI mode. That has to be done as the very last over the EFI Shell. However, the following command can be used later to adjust the boot entry when Linux is running in native EFI.
sudo efibootmgr -c -d /dev/sda -p 1 -L "Ubuntu (efistub)" -l /EFI/ubuntu/vmlinuz.efi -u "root=/dev/sda4 rw initrd=/EFI/ubuntu/initrd.img quiet splash"
The syntax is correct for this example here. Otherwise the arguments
-d
and-p
must be changed according to the used partition layout. The EFI ESP is/dev/sda1
while theroot=
partition issda4
.
Finally, make a reboot, install rEFInd from CD, boot into it and launch the EFI shell. The last step establishes the boot entry in the stock Apple EFI bootloader. This is not absolutely necessary when only rEFInd is used as bootloader. However, in that example here the command would be:
vmlinuz.efi root=/dev/sda4 ro initrd=\EFI\ubuntu\initrd.img
Regarding rEFInd this results now in a configuration in which two vmlinuz.efi
boot options exists. The first is located in the esp partition sda1
and can be loaded directly from the Apple stock EFI loader. The other one is located in the root partition sda4
(or in its boot
folder). That second vmlinuz.efi
can be loaded from rEFInd but not from the stock Apple loader. Conversely, rEFInd seems unable to load the first vmlinuz.efi file without additional information regarding the root partition. (The boot process will hang and a BusyBox shell will be displayed.)
Optional further steps, only necessary on restricted "vBIOS not exposed in EFI" systems:
As mentioned at the beginning, it is sometimes necessary to start only the bare Linux kernel (without the "vmlinuz loader") directly from rEFInd to avoid tough problems like the "vBIOS not exposed in EFI" issue. In this case, the kernel must also have an efi extension. This requires a manual adjustment because the kernel name changes with every kernel update. The syntax may look like:
sudo cp /boot/vmlinuz-5.4.0-65-generic /boot/vmlinuz-5.4.0-65-generic.efi
In some situations it may be necessary to delete the previously generated vmlinuz.efi
file. But i recommend to try it first out without deleting it.
sudo rm /boot/vmlinuz.efi
Last of all, if everything works as expected the esp
partition can be auto-mounted in fstab
with the following command. (This is needed for the hook to updated the kernel loader files automatically.)
/dev/sda1 /boot/esp vfat rw,auto,user,uid=1000,gid=1000,utf8 0 0
or
/dev/sda1 /boot/efi vfat rw,auto,user,uid=1000,gid=1000,utf8 0 0
All suggestions for further improvements are welcome! ;-)