trueos / trueos-core

59 stars 18 forks source link

EFI Stub Booting, and manual ESP mounts for gummiboot booting? #49

Closed fpqc closed 7 years ago

fpqc commented 8 years ago

I have a few OSes installed on my system, with a large (512 mb) EFI system partition (/dev/ada1p0) and the systemd-boot bootloader (don't worry, it's just Gummiboot rebranded and doesn't have any systemd dependencies). It's really nice and easy to configure for Linux and Non-Linux Operating systems, but it only supports booting FreeBSD (and PC-BSD/TrueOS) by manually copying boot1.efi from the FreeBSD livedrive to the ESP, and adding a loader entry pointing to it (which then chainloads from the zpool).

Is there any chance that TrueOS can support a systemd-boot style bootloader, by mounting the ESP as /boot and building an initramfs like Arch linux does with mkinitcpio, then building loader entries in the bootloader? This is a much better system than Grub-EFI, which is extremely complicated and doubles or triples the work.

fpqc commented 8 years ago

Hi, so pkgdemon and I discussed this a bit more, and when doing custom partitioning in the installer, there are a few extremely scary lines.

if [ "$BOOTMODE" = "UEFI" ]; then
   # Need to enable EFI booting, lets add the partition
   rc_halt "gpart add -a 4k -s 100M -t efi ${_intDISK}"
   rc_halt "newfs_msdos -F 16 ${_intDISK}p1"
   if [ -z "${EFI_POST_SETUP}" ] ; then
     EFI_POST_SETUP="${_intDISK}"
   else
     EFI_POST_SETUP="${EFI_POST_SETUP} ${_intDISK}"
   fi

This is creating a partition without any user interaction, which is potentially scary. The installer should ask the user to specify the EFI system partition, if it already exists. Also, ideally, you should not overwrite bootx64.efi, which is the stock entry in the EFI firmware. The right way to do it would probably be this:

After a user tells the installer where the existing EFI System Partition is, if it exists (mine is ada0p1), TrueOS efi boot object should be moved to (ESP)/EFI/BOOT/bootx64-trueos.efi.

Then, this boot object needs to be registered with the Motherboard's efi firmware and stored in the motherboard's nvram by means of the UEFI API (Don't know if FreeBSD has the driver to access this API baked in, but it works in Linux).

The other option is to chainload this boot object from an EFI multi-loader like systemd-boot, which is a simple and easily-configurable loader, where entries can be added with a two-to-three-line text file.

I would like to see the second one, since it requires only one entry to be added to the NVRAM for many many operating systems, but doing it the other way, directly adding an efi entry to NVRAM also works.

Nowadays, many Linux distros also support copying the kernel and initramfs image directly to the ESP as stub-bootable images. This is basically an EFI-bootable image of a minimal rootfs, that is then used to mount the full system. It contains the kernel, the kernel modules, and some other stuff. This would be ideal for TrueOS, but it might be a lot of work to implement, since FreeBSD does not support stub-booting and initramfs images.

fpqc commented 8 years ago

Here's a FreeBSD reference on this stuff:

https://wiki.freebsd.org/201305DevSummit/UEFI

Specifically these two lines:

Installation

The following issues exist:

It's interesting to note that FreeBSD's installer still doesn't ask you if you already have an EFI system partition, and it still does not make an EFI boot entry in the NVRAM (that's why it just automatically extracts as bootx64.efi, which is the default).

kmoore134 commented 7 years ago

Ok, I've looked at the code. Our EFI install only runs that particular bit when doing a fresh installation. If you are installing to an existing disk, I.E. a "new" partition, it'll search for and mount/reuse the existing EFI partition.

That being said, it doesn't fix the underlying problem with updating NVRAM. As mentioned, FreeBSD doesn't have support for this yet, which requires we still use the bootx64.efi filename. Once this lands though, I will be adding support to our installer to instead create bootx64-trueos.efi and make EFI entry for it (as linux can do)