Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin to automatically add UEFI boot entry after kernel stub install #19

Closed
Biosias opened this issue Mar 6, 2024 · 12 comments
Closed

Comments

@Biosias
Copy link
Contributor

Biosias commented Mar 6, 2024

Hello,

we would like to ditch bootloaders on our servers and just use plain UEFI direct kernel boot using Kernel as EFI-stub. (Just module-less kernel EFI-stub without using any initramfs)

I would like to create postinstall script similar to 91-grub-mkconfig.install which would, upon installation of a new kernel, also add corresponding UEFI boot entry using efibootmgr.

I would like to know if functionality like this would be acceptable from your side or if there is some explicit reason to not do it this way.

If it would be ok from your side, I will create pull request to add this postinstall script. Otherwise I will keep it in our private overlay.

@AndrewAmmerlaan
Copy link
Collaborator

AndrewAmmerlaan commented Mar 6, 2024

I would like to know if functionality like this would be acceptable from your side or if there is some explicit reason to not do it this way.

Yes I think this is acceptable, provided it is done in a reliable way. I had been thinking about something like this, but did not get around to writing a proper plugin script to actually do it.

A couple of considerations:

  • efibootmgr needs to know the disk and partition ID of the ESP that the (unified) kernel image was installed on
  • The plugin should work for at least the uki layout (UKIs in ESP/EFI/Linux) and for the bls layout (kernel (+initrd)) in ESP/ENTRY_TOKEN/KERNEL_VERSION.
    • Optionally: it may also create entries (for UKI or kernel (+initrd)) when the layout is set to compat, but it should then check that the mount point of the ESP is /boot otherwise it will not work.
  • For plain kernel images with an accompanying initrd , it should add --unicode 'initrd=\initramfs.img'
  • It should read kernel command line arguments from some location (e.g. /etc/kernel/cmdline) and add them to the efibootmgr entry (as above for the initrd)
  • It should work at least with sytemd's kernel-install, it should not only add the entry on kernel-install add but also again delete the entry on kernel-install remove so eclean-kernel will automatically remove entries for kernels that are being removed.
    • Optionally: Provide similar functionality for the traditional installkernel, problem here is that there is no way to automatically remove the entry on kernel removal, so entries will heap up over time and possibly create problems. So perhaps it is best to stick with just a plugin for systemd's kernel-install.

@AndrewAmmerlaan
Copy link
Collaborator

  • It should work at least with sytemd's kernel-install, it should not only add the entry on kernel-install add but also again delete the entry on kernel-install remove so eclean-kernel will automatically remove entries for kernels that are being removed.

Thinking about this a bit more. Since we can only delete entries with efibootmgr if we know the hex of the entry, we should store the hex of the created entries somewhere so we can access it when the kernel is to be removed. I would propose something like this:

  • /boot/kernel-x.y.z.efibootmgr (for layout=compat)
  • /efi/ENTRY_TOKEN/x.y.z/efibootmgr (for layout=bls)
  • /efi/EFI/Linux/ENTRY_TOKEN-x.y.z.efibootmgr (for layout=uki)

These files would contain the hex belonging to the uefi entry for the associated (unified) kernel image.

@Biosias
Copy link
Contributor Author

Biosias commented Mar 11, 2024

I got inspired by grub-mkconfig and want to do it in a as simple way as possible. Currently I'm experimenting with following logic for adding and removing uefi entries:

  1. Find all mounted EFI Partitions
  2. Go through them and find all .efi files in them
  3. Check if UEFI entry exists for each of these EFI files
  4. If not create it
  5. If yes, just print that it exists
    .... currently trying to think the best way for removing UEFI etries that are not used.

My idea is to do something similar and for each entry verify that said efi file for that entry exists. If not, delete the entry.

Some other ideas I have:

If hex number of the entry is for example above 0100 don't touch them. To allow custom entries. In this way, we don't need to store those values anywhere since we will know that entries in a certain range of hex values are created by us.

Anything that we would like to include in -u of efibootmgr would be taken from config file, similar how grub handles this.

@Biosias
Copy link
Contributor Author

Biosias commented Mar 11, 2024

If hex number of the entry is for example above 0100 don't touch them. To allow custom entries. In this way, we don't need to store those values anywhere since we will know that entries in a certain range of hex values are created by us.

Just thinking about this more, the range of hex values of automatically generated entries should probably be something like 0100 - 0200 to not mess with default entries like netboot etc....

@AndrewAmmerlaan
Copy link
Collaborator

My idea is to do something similar and for each entry verify that said efi file for that entry exists. If not, delete the entry.

Hmm, I hadn't thought about it that way. But this could work too, the difficulty we might face with this approach is that we somehow have to reliably parse the output of efibootmgr.

If hex number of the entry is for example above 0100 don't touch them. To allow custom entries. In this way, we don't need to store those values anywhere since we will know that entries in a certain range of hex values are created by us.

Just thinking about this more, the range of hex values of automatically generated entries should probably be something like 0100 - 0200 to not mess with default entries like netboot etc....

I agree, we should definitely define some range for auto-generated entries. However, I tried yesterday to use the --index argument of efibootmgr and ran into this problem: rhboot/efibootmgr#206

Until that is fixed this is not going to work unfortunately. We should also investigate if other tools or operating systems use some predefined range so we don't interfere with that.

@AndrewAmmerlaan
Copy link
Collaborator

Something else worth looking into is what Fedora is doing, because they seem to be aiming to do something very similar: https://www.phoronix.com/news/Fedora-40-Boot-UKIs-Directly

Perhaps we don't have to reinvent the wheel from scratch.

@Biosias
Copy link
Contributor Author

Biosias commented Mar 11, 2024

Until that is fixed this is not going to work unfortunately. We should also investigate if other tools or operating systems use some predefined range so we don't interfere with that.

Good point, absolutely agree with that.

However, I tried yesterday to use the --index argument of efibootmgr and ran into this problem: rhboot/efibootmgr#206

I don't think this is a problem. -I only changes the bootorder not hex num of the entry. I first thought defining it isn't possible but with following it can be specified efibootmgr --create -b 0100 --disk /dev/nvme0n1p1 --label "Gentoo test" --loader "\bzImage.efi" . Not being able to define boot order for now is a shame but the default is that the last created entry will be set to boot first.

@AndrewAmmerlaan
Copy link
Collaborator

I don't think this is a problem. -I only changes the bootorder not hex num of the entry. I first thought defining it isn't possible but with following it can be specified efibootmgr --create -b 0100 --disk /dev/nvme0n1p1 --label "Gentoo test" --loader "\bzImage.efi" . Not being able to define boot order for now is a shame but the default is that the last created entry will be set to boot first.

ooooooh, oops, I completely misunderstood the manual. I thought --index was supposed to create the new entry with a specific hex.

@Biosias
Copy link
Contributor Author

Biosias commented Mar 11, 2024

Something else worth looking into is what Fedora is doing, because they seem to be aiming to do something very similar: https://www.phoronix.com/news/Fedora-40-Boot-UKIs-Directly

Seems very interesting, will have to check how flexible it will be. Gentoo installs tend to be of a more exotic kind from what I've seen so far. But at least it could be a good inspiration, if nothing more

ooooooh, oops, I completely misunderstood the manual. I thought --index was supposed to create the new entry with a specific hex.

No problem, the manual isn't very straight forward with this functionality. To be fair I stumbled upon it only through trial and error.

@Biosias
Copy link
Contributor Author

Biosias commented Mar 11, 2024

Will create pull request shortly so we can discuss above actual code.

@Biosias
Copy link
Contributor Author

Biosias commented Mar 11, 2024

#20

gentoo-bot pushed a commit to gentoo/gentoo that referenced this issue Mar 15, 2024
Closes: projg2/installkernel-gentoo#20
Closes: projg2/installkernel-gentoo#19
Signed-off-by: Andrew Ammerlaan <andrewammerlaan@gentoo.org>
@AndrewAmmerlaan
Copy link
Collaborator

Resolved in version 29.

Documentation will follow later, short version is:

  • enable USE=efistub on sys-kernel/installkernel, then reinstall kernel

Let me know if there are any problems. It's stable masked for now because this is still a bit new and experimental.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants