diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index 5e576367eb2f..f1874f239778 100644
--- a/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -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
}
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index 61c34cc2f034..e47afd061e2b 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -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 grub-install with
+ --removable.
+
+ Unless turn this on, GRUB will install itself somewhere (exactly
+ where depends on other config variables) in
+ boot.loader.efi.efiSysMountPoint. If you've set
+ boot.loader.efi.canTouchEfiVariables *AND* you
+ are currently booted in UEFI mode, then GRUB will use
+ efibootmgr 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 "efibootmgr: EFI variables are not supported on
+ this system.").
+
+ If you do turn this feature on, then GRUB will install itself
+ in a specific special location within efiSysMountPoint
+ (namely EFI/boot/boot$arch.efi) which is the firmwares
+ are hardcoded to try first, regardless of NVRAM EFI variables.
+
+ To summarize, turn this on if:
+
+ You are installing NixOS and want it to boot in UEFI mode,
+ but you are currently booted in legacy mode
+ You want to make a drive that will boot regardless of
+ the NVRAM state of the computer (like a USB "removable" drive)
+ You simply dislike the idea of depending on some NVRAM
+ state to make your drive bootable
+
+ '';
+ };
+
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 != [ ];
diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl
index 06eece5025f8..b93395300b72 100644
--- a/nixos/modules/system/boot/loader/grub/install-grub.pl
+++ b/nixos/modules/system/boot/loader/grub/install-grub.pl
@@ -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";
}