After a day of research, I can now answer my own Question: yes it is possible, and you can even use that partition as /boot and store your kernels/initramfs/etc. there.
Requirements:
- Grub >= 2.00 (1.98 and 1.99 do not work)
- Grub must be installed from a Linux kernel, that has support for EFI variables (
CONFIG_EFI_VARS
compiled in or as module efivars
)
- For creating the EFI boot entry you will need
efibootmgr
Setup:
First mount your EFI partition to /boot
mount /dev/sdX1 /boot
If you look at the mount entry, you will see, that it is simply a FAT(32) partition. Under /boot
you should find a directory efi
.
As grub will call efibootmgr
, you should load evivars
, if it is not compiled into the kernel:
modprobe efivars
Now you can install grub:
# Replace x86_64 with i386 for 32 bit installations
grub2-install --target=x86_64-efi
Grub installs its files as usual to /boot/grub2
. If everything worked correctly, you should now also have a folder /boot/efi/grub2
or /boot/efi/<name_of_your_distro>
. With --bootloader-id=insert_name_here
you can also specify the name for the folder yourself.
Grub calls efibootmgr
automatically and creates a boot entry with that name in the EFI boot menu (in my case, that means it shows up as a bootable device in the EFI menu, not sure if this is the case on every EFI board)
Further setup does not differ from usual grub2 setup, grub2-mkconfig
will add the appropriate modules for EFI to your grub.cfg
.
Chainloading Windows:
As I asked for a dual boot with Windows, I will include the grub configuration for chainloading it:
Chainloading a Windows installation on EFI is slightly different from one on a MBR disk. You won't need the ntfs
or part_mbr
modules, instead fat
and part_gpt
are needed.
Also, setting root is not required, this information is stored by Windows' own boot manager. Instead specify the search
command. The parameters needed for it can be determined by
grub-probe --target=hints_string /boot/efi/EFI/Microsoft/Boot/bootmgfw.efi
This will give you the parameters for search specifying the location of the EFI partition, it should look something like:
--hint-bios=hd0,gpt1 --hint-efi=hd0,gpt1 --hint-baremetal=ahci0,gpt1 1ce5-7f28
Instead of telling chainloader
the number of sectors to read, you will need to set the path to Windows' EFI loader in the EFI partition. This is the same for all Windows EFI installations. The resulting entry should look like this:
menuentry "Microsoft Windows x86_64 UEFI-GPT" {
insmod part_gpt
insmod fat
insmod search_fs_uuid
insmod chain
search --fs-uuid --no-floppy --set=root <insert ouput from grub-probe here>
chainloader /efi/Microsoft/Boot/bootmgfw.efi
}
Sources: These cover some more cases, if you want to boot from EFI, they are worth reading:
I don't know why you're using grub in the first place. UEFI acts as a boot
loader and it allows to select different operating systems or individual
kernels from a boot menu. Although there are some exceptions, it usually is
not required to chain a second boot loader, grub in this case.
You mention, you installed elementary OS instead of Fedora, which means you
only need to load one operating system. Here I present a way to do it
without using grub. The kernel needs to be compiled with
EFI_STUB, if that's the case you can check with
grep EFI_STUB /boot/config-<version>
Copy the kernel and initramfs to the ESP (EFI system partition)
cp /boot/vmlinuz-<version> /boot/efi/EFI/elementary/vmlinuz-<version>.efi
cp /boot/initrd.img-<version> /boot/efi/EFI/elementary/initrd.img-<version>
Register kernel as boot option in UEFI
echo "root=UUID=<disk_uuid> ro quiet rootfstype=ext4 add_efi_memmap initrd=\\EFI\\elementary\\initrd.img-<version>" |
iconv -f ascii -t ucs2 |
efibootmgr \
--create --gpt \
--disk /dev/<disk> --part <partition_number> \
--label "Elementary OS" \
--loader "\\EFI\\elementary\\vmlinuz-<version>.efi" \
--write-signature --append-binary-args -
The --disk
argument takes the device name of the disk, e.g.
--disk /dev/sda
, the --part
argument takes the partition number
of the ESP, e.g. 4. You can find the ESP partition number with the
following command:
gdisk -l /dev/sda | awk '$6=="EF00" {print $1}'
Ensure that you repeat the steps after each kernel update
Either you this manually (just repeat the steps above) or you write
a small script which does the job. To fully automatise it, the
script could be hooked into the kernel post-install procedure, into
the initramfs post-update procedure and into the kernel postrm
procedure (to remove the UEFI boot entry). Actually, I don't know
why this isn't done by default in the distributions, it's just a few
lines of code.
Best Answer
You're advised to read EFI bootloader principles -- this should help you understand that installing a bootloader into MBR or a partition's boot sector is not going to do anything when booting in EFI mode. You basically want to establish or reuse an existing ESP (EFI System Partition) on a GPT partitioned disk and to store all of your bootloaders in its subdirectories.