grub: add boot.loader.grub.efiInstallAsRemovable

Closes #16374
This commit is contained in:
obadz 2016-09-13 18:46:53 +01:00
parent a0b643ed06
commit 1c9ac8aabc
3 changed files with 58 additions and 6 deletions

View file

@ -527,8 +527,11 @@ EOF
# Use the GRUB 2 boot loader.
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
# boot.loader.grub.efiSupport = true;
# boot.loader.grub.efiInstallAsRemovable = true;
# boot.loader.efi.efiSysMountPoint = "/boot/efi";
# Define on which hard drive you want to install Grub.
# boot.loader.grub.device = "/dev/sda";
# boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
EOF
}

View file

@ -55,7 +55,7 @@ let
inherit (cfg)
version extraConfig extraPerEntryConfig extraEntries
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels
default fsIdentifier efiSupport gfxmodeEfi gfxmodeBios;
default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios;
path = (makeBinPath ([
pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfs-progs
pkgs.utillinux ] ++ (if cfg.efiSupport && (cfg.version == 2) then [pkgs.efibootmgr ] else [])
@ -357,6 +357,44 @@ in
'';
};
efiInstallAsRemovable = mkOption {
default = false;
example = true;
type = types.bool;
description = ''
Whether to invoke <literal>grub-install</literal> with
<literal>--removable</literal>.
Unless turn this on, GRUB will install itself somewhere (exactly
where depends on other config variables) in
<literal>boot.loader.efi.efiSysMountPoint</literal>. If you've set
<literal>boot.loader.efi.canTouchEfiVariables</literal> *AND* you
are currently booted in UEFI mode, then GRUB will use
<literal>efibootmgr</literal> to modify the boot order in the NVRAM's
EFI variables of your computer to include this location. If you are
*not* booted in UEFI mode at the time grub is being installed, the
NVRAM will not be modified, and your system will not find GRUB at
boot time. GRUB will still succeed (althgouh you'll see a warning
printed "<literal>efibootmgr: EFI variables are not supported on
this system.</literal>").
If you do turn this feature on, then GRUB will install itself
in a specific special location within <literal>efiSysMountPoint</literal>
(namely <literal>EFI/boot/boot$arch.efi</literal>) which is the firmwares
are hardcoded to try first, regardless of NVRAM EFI variables.
To summarize, turn this on if:
<itemizedlist>
<listitem>You are installing NixOS and want it to boot in UEFI mode,
but you are currently booted in legacy mode</listitem>
<listitem>You want to make a drive that will boot regardless of
the NVRAM state of the computer (like a USB "removable" drive)</listitem>
<listitem>You simply dislike the idea of depending on some NVRAM
state to make your drive bootable</listitem>
</itemizedlist>
'';
};
enableCryptodisk = mkOption {
default = false;
type = types.bool;
@ -484,6 +522,14 @@ in
assertion = !cfg.trustedBoot.enable || cfg.trustedBoot.systemHasTPM == "YES_TPM_is_activated";
message = "Trusted GRUB can break the system! Confirm that the system has an activated TPM by setting 'systemHasTPM'.";
}
{
assertion = cfg.efiInstallAsRemovable -> cfg.efiSupport;
message = "If you wish to to use boot.loader.grub.efiInstallAsRemovable, then turn on boot.loader.grub.efiSupport";
}
{
assertion = cfg.efiInstallAsRemovable -> !config.boot.loader.efi.canTouchEfiVariables;
message = "If you wish to to use boot.loader.grub.efiInstallAsRemovable, then turn off boot.loader.efi.canTouchEfiVariables";
}
] ++ flip concatMap cfg.mirroredBoots (args: [
{
assertion = args.devices != [ ];

View file

@ -60,6 +60,7 @@ my $grubTargetEfi = get("grubTargetEfi");
my $bootPath = get("bootPath");
my $storePath = get("storePath");
my $canTouchEfiVariables = get("canTouchEfiVariables");
my $efiInstallAsRemovable = get("efiInstallAsRemovable");
my $efiSysMountPoint = get("efiSysMountPoint");
my $gfxmodeEfi = get("gfxmodeEfi");
my $gfxmodeBios = get("gfxmodeBios");
@ -544,13 +545,15 @@ if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
# install EFI GRUB
if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both")) {
print STDERR "installing the GRUB $grubVersion EFI boot loader into $efiSysMountPoint...\n";
my @command = ("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint");
if ($canTouchEfiVariables eq "true") {
system("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint", "--bootloader-id=$bootloaderId") == 0
or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n";
push @command, "--bootloader-id=$bootloaderId";
} else {
system("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint", "--no-nvram") == 0
or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n";
push @command, "--no-nvram";
push @command, "--removable" if $efiInstallAsRemovable eq "true";
}
(system @command) == 0 or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n";
}