How to add bootentry booting straight into latest generation?

Hey!

How would I define a boot loader that boots immedietely into the latest nixos generation? Typically we boot first into a systemd-boot menu, then choosing the wanted generation.

context

I’m using refind as my primary bootmanager. I want to keep that.

Refind can’t boot into nixos, so the way it works is that refind shows systemd-boot boot option, booting into it boots into the systemd-boot menu where we choose the nixos generation and boot into it - so two step process. Refind naturally picks up existing boot loaders on the system and here it picks up the systemd bootloader meant to boot nixos.

How would I define a boot loader (preferably just by configuring the systemd nixos bootloader) to boot immedietely into the latest generation?

I would then put both options into my refind boot menu - one going straight into nixos and second that lets me choose the generation in an emergency where I brick my system.

thanks!

I don’t think there are any issues with using refind as a boot manager directly in theory. Something like this abandoned PR would need to be written though: https://github.com/NixOS/nixpkgs/pull/58121

That’s admittedly easier, just set boot.loader.timeout to 0. Technically there will still be multiple entries if you hold space, but that should be fine for your purposes?

If you want to write another entry with other settings, you can use boot.loader.systemd-boot.extraEntries for that.

1 Like

Right, there were some PR attempts at doing that, but I don’t have the willingness to push these through. The solution you describe is way simpler

@TLATER EDIT:
extra entries would append to the list of nixos generations shown by systemd. But how to create a second bootloader that differs from the systemd bootloader only in having timeout set to 0?

I kinda can see where is the data I want to modify on my boot partition, but I don’t know how nixos creates it and then how it boots to just modify it.
There’s:

/boot/
  - EFI/
    - BOOT
    - refind
    - systemd
  - loader/
    - loader.conf
    - entries/
      - nixos-generation-17.conf

and now refind is the bootloader that loads first (my guess: is it because of something set in BOOT/BOOTX64.efi? either way refind makes itself default by running script refind-install).
Then in the refind menu systemd entry shows. Systemd menu depends on the content of /loader. loader/loader.conf:

timeout 5
default nixos-generation-17.conf

So it is apparent to me that i.e. setting boot.loader.timeout=0 would alter the above file or setting boot.loader.systemd-boot.extraEntries would add stuff to loader/entries.

But how to create a sort of parallel copy of BOOT/efi/systemd that uses a timeout of 0 and the same most recent generation as a default?

Ah, duh, of course, you’re right. My bad.

Only on broken motherboard firmwares, that’s the fallback. This is supposed to be configured using efivars, which is an API the firmware offers operating systems. You can either change this using tools like efivar or in the BIOS.

Refind/systemd-boot also set those variables during installation, unless it’s disabled.

That’s more tricky then, there’s definitely no support for this in the NixOS modules. The kernel itself can just be booted afaik, but you would need to manually configure a refind entry for the kernel in question with the correct command line args.

You could write a script that does that, similar to what is in the first PR I linked, but is much simpler and only figures out what the installed kernel is to write configuration for it.

To leave the systemd-boot entry for the other kernel entries you would then have to figure out how exactly boot.installBootLoader works, so you can run both bootloader installation scripts.

Honestly might just be better to revive that refind PR at that point.

Alternatively you could just set the timeout to 0, and rely on systemd-boot’s feature to show the boot menu if you hold shift at boot for disaster recovery, keeping only one boot entry for NixOS.

1 Like

Once more the simple wins haha. That’s what I’m going to do for now. Afair the above pr was a working solution according to the author - it just lacked proper tests - so I should try it at some point the way it is. Thanks a lot for the explanations!