2014-04-14 16:26:48 +02:00
|
|
|
|
{ config, lib, pkgs, ... }:
|
2009-01-02 17:07:34 +01:00
|
|
|
|
|
2014-04-14 16:26:48 +02:00
|
|
|
|
with lib;
|
2009-01-02 17:07:34 +01:00
|
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
2012-05-14 03:53:47 +02:00
|
|
|
|
cfg = config.boot.loader.grub;
|
|
|
|
|
|
2015-01-14 10:30:57 +01:00
|
|
|
|
efi = config.boot.loader.efi;
|
|
|
|
|
|
2014-08-31 18:18:13 +02:00
|
|
|
|
realGrub = if cfg.version == 1 then pkgs.grub
|
2015-02-13 23:40:41 +01:00
|
|
|
|
else if cfg.zfsSupport then pkgs.grub2.override { zfsSupport = true; }
|
|
|
|
|
else pkgs.grub2;
|
2013-06-04 14:05:07 +02:00
|
|
|
|
|
|
|
|
|
grub =
|
|
|
|
|
# Don't include GRUB if we're only generating a GRUB menu (e.g.,
|
|
|
|
|
# in EC2 instances).
|
|
|
|
|
if cfg.devices == ["nodev"]
|
|
|
|
|
then null
|
|
|
|
|
else realGrub;
|
2009-12-15 22:11:39 +01:00
|
|
|
|
|
2015-01-14 10:30:57 +01:00
|
|
|
|
grubEfi =
|
|
|
|
|
# EFI version of Grub v2
|
2015-04-29 20:18:47 +02:00
|
|
|
|
if cfg.efiSupport && (cfg.version == 2)
|
2015-02-13 23:40:41 +01:00
|
|
|
|
then realGrub.override { efiSupport = cfg.efiSupport; }
|
2015-01-14 10:30:57 +01:00
|
|
|
|
else null;
|
|
|
|
|
|
2012-07-25 15:27:51 +02:00
|
|
|
|
f = x: if x == null then "" else "" + x;
|
|
|
|
|
|
2012-07-25 01:16:27 +02:00
|
|
|
|
grubConfig = pkgs.writeText "grub-config.xml" (builtins.toXML
|
2012-07-25 15:27:51 +02:00
|
|
|
|
{ splashImage = f config.boot.loader.grub.splashImage;
|
|
|
|
|
grub = f grub;
|
2015-02-09 04:31:14 +01:00
|
|
|
|
grubTarget = f (grub.grubTarget or "");
|
2012-12-16 21:41:47 +01:00
|
|
|
|
shell = "${pkgs.stdenv.shell}";
|
2013-06-04 14:05:07 +02:00
|
|
|
|
fullVersion = (builtins.parseDrvName realGrub.name).version;
|
2015-01-14 10:30:57 +01:00
|
|
|
|
grubEfi = f grubEfi;
|
2015-02-16 20:19:44 +01:00
|
|
|
|
grubTargetEfi = if cfg.efiSupport && (cfg.version == 2) then f (grubEfi.grubTarget or "") else "";
|
2015-01-14 10:30:57 +01:00
|
|
|
|
inherit (efi) efiSysMountPoint canTouchEfiVariables;
|
2013-06-04 14:05:07 +02:00
|
|
|
|
inherit (cfg)
|
2012-07-25 01:16:27 +02:00
|
|
|
|
version extraConfig extraPerEntryConfig extraEntries
|
2012-12-16 21:41:47 +01:00
|
|
|
|
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels timeout
|
2015-01-14 10:30:57 +01:00
|
|
|
|
default devices fsIdentifier efiSupport;
|
|
|
|
|
path = (makeSearchPath "bin" ([
|
2014-08-31 18:18:13 +02:00
|
|
|
|
pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfsProgs
|
2015-01-14 10:30:57 +01:00
|
|
|
|
pkgs.utillinux ] ++ (if cfg.efiSupport && (cfg.version == 2) then [pkgs.efibootmgr ] else [])
|
|
|
|
|
)) + ":" + (makeSearchPath "sbin" [
|
2014-08-31 18:18:13 +02:00
|
|
|
|
pkgs.mdadm pkgs.utillinux
|
2013-07-08 01:44:48 +02:00
|
|
|
|
]);
|
2012-07-25 01:16:27 +02:00
|
|
|
|
});
|
2011-09-14 20:20:50 +02:00
|
|
|
|
|
2009-01-02 17:07:34 +01:00
|
|
|
|
in
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
2009-09-29 11:50:38 +02:00
|
|
|
|
###### interface
|
|
|
|
|
|
|
|
|
|
options = {
|
2009-10-13 23:39:23 +02:00
|
|
|
|
|
2009-09-29 11:50:38 +02:00
|
|
|
|
boot.loader.grub = {
|
|
|
|
|
|
|
|
|
|
enable = mkOption {
|
2013-11-27 16:54:20 +01:00
|
|
|
|
default = !config.boot.isContainer;
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.bool;
|
2009-09-29 11:50:38 +02:00
|
|
|
|
description = ''
|
2009-10-13 23:39:23 +02:00
|
|
|
|
Whether to enable the GNU GRUB boot loader.
|
2009-09-29 11:50:38 +02:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2009-10-13 23:39:18 +02:00
|
|
|
|
version = mkOption {
|
2013-10-07 11:06:08 +02:00
|
|
|
|
default = 2;
|
|
|
|
|
example = 1;
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.int;
|
2009-10-13 23:39:18 +02:00
|
|
|
|
description = ''
|
2013-10-07 11:05:33 +02:00
|
|
|
|
The version of GRUB to use: <literal>1</literal> for GRUB
|
2013-10-07 11:06:08 +02:00
|
|
|
|
Legacy (versions 0.9x), or <literal>2</literal> (the
|
|
|
|
|
default) for GRUB 2.
|
2009-10-13 23:39:18 +02:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2009-09-29 11:50:38 +02:00
|
|
|
|
device = mkOption {
|
|
|
|
|
default = "";
|
|
|
|
|
example = "/dev/hda";
|
2013-10-30 11:02:04 +01:00
|
|
|
|
type = types.str;
|
2009-10-13 23:39:23 +02:00
|
|
|
|
description = ''
|
2012-05-14 03:53:47 +02:00
|
|
|
|
The device on which the GRUB boot loader will be installed.
|
|
|
|
|
The special value <literal>nodev</literal> means that a GRUB
|
|
|
|
|
boot menu will be generated, but GRUB itself will not
|
|
|
|
|
actually be installed. To install GRUB on multiple devices,
|
|
|
|
|
use <literal>boot.loader.grub.devices</literal>.
|
2012-03-08 22:37:30 +01:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
devices = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
example = [ "/dev/hda" ];
|
2013-10-30 17:37:45 +01:00
|
|
|
|
type = types.listOf types.str;
|
2012-03-08 22:37:30 +01:00
|
|
|
|
description = ''
|
|
|
|
|
The devices on which the boot loader, GRUB, will be
|
|
|
|
|
installed. Can be used instead of <literal>device</literal> to
|
2012-05-14 03:53:47 +02:00
|
|
|
|
install grub into multiple devices (e.g., if as softraid arrays holding /boot).
|
2009-10-13 23:39:23 +02:00
|
|
|
|
'';
|
2009-09-29 11:50:38 +02:00
|
|
|
|
};
|
|
|
|
|
|
2014-08-27 09:26:40 +02:00
|
|
|
|
configurationName = mkOption {
|
|
|
|
|
default = "";
|
|
|
|
|
example = "Stable 2.6.21";
|
|
|
|
|
type = types.str;
|
|
|
|
|
description = ''
|
|
|
|
|
GRUB entry name instead of default.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2012-04-02 19:19:21 +02:00
|
|
|
|
extraPrepareConfig = mkOption {
|
|
|
|
|
default = "";
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.lines;
|
2012-04-02 19:19:21 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Additional bash commands to be run at the script that
|
|
|
|
|
prepares the grub menu entries.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2010-06-17 00:18:26 +02:00
|
|
|
|
extraConfig = mkOption {
|
|
|
|
|
default = "";
|
|
|
|
|
example = "serial; terminal_output.serial";
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.lines;
|
2010-06-17 00:18:26 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Additional GRUB commands inserted in the configuration file
|
|
|
|
|
just before the menu entries.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2010-07-22 16:40:29 +02:00
|
|
|
|
extraPerEntryConfig = mkOption {
|
|
|
|
|
default = "";
|
|
|
|
|
example = "root (hd0)";
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.lines;
|
2010-07-22 16:40:29 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Additional GRUB commands inserted in the configuration file
|
|
|
|
|
at the start of each NixOS menu entry.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2009-09-29 11:50:38 +02:00
|
|
|
|
extraEntries = mkOption {
|
|
|
|
|
default = "";
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.lines;
|
2009-10-13 23:39:23 +02:00
|
|
|
|
example = ''
|
2012-03-28 12:34:40 +02:00
|
|
|
|
# GRUB 1 example (not GRUB 2 compatible)
|
2009-09-29 11:50:38 +02:00
|
|
|
|
title Windows
|
|
|
|
|
chainloader (hd0,1)+1
|
2012-03-28 12:34:40 +02:00
|
|
|
|
|
|
|
|
|
# GRUB 2 example
|
2014-04-20 19:41:15 +02:00
|
|
|
|
menuentry "Windows 7" {
|
|
|
|
|
chainloader (hd0,4)+1
|
2012-03-28 12:34:40 +02:00
|
|
|
|
}
|
2009-10-13 23:39:23 +02:00
|
|
|
|
'';
|
|
|
|
|
description = ''
|
|
|
|
|
Any additional entries you want added to the GRUB boot menu.
|
|
|
|
|
'';
|
2009-09-29 11:50:38 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
extraEntriesBeforeNixOS = mkOption {
|
|
|
|
|
default = false;
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.bool;
|
2009-10-13 23:39:23 +02:00
|
|
|
|
description = ''
|
2009-09-29 11:50:38 +02:00
|
|
|
|
Whether extraEntries are included before the default option.
|
2009-10-13 23:39:23 +02:00
|
|
|
|
'';
|
2009-09-29 11:50:38 +02:00
|
|
|
|
};
|
|
|
|
|
|
2013-10-02 12:29:07 +02:00
|
|
|
|
extraFiles = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = literalExample ''
|
2013-10-30 16:19:07 +01:00
|
|
|
|
{ "memtest.bin" = "''${pkgs.memtest86plus}/memtest.bin"; }
|
2013-10-02 12:29:07 +02:00
|
|
|
|
'';
|
|
|
|
|
description = ''
|
|
|
|
|
A set of files to be copied to <filename>/boot</filename>.
|
|
|
|
|
Each attribute name denotes the destination file name in
|
|
|
|
|
<filename>/boot</filename>, while the corresponding
|
|
|
|
|
attribute value specifies the source file.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2009-09-29 11:50:38 +02:00
|
|
|
|
splashImage = mkOption {
|
2015-02-23 18:00:21 +01:00
|
|
|
|
type = types.nullOr types.path;
|
2013-10-23 20:06:39 +02:00
|
|
|
|
example = literalExample "./my-background.png";
|
2009-10-13 23:39:23 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Background image used for GRUB. It must be a 640x480,
|
2009-09-29 11:50:38 +02:00
|
|
|
|
14-colour image in XPM format, optionally compressed with
|
|
|
|
|
<command>gzip</command> or <command>bzip2</command>. Set to
|
2009-10-13 23:39:23 +02:00
|
|
|
|
<literal>null</literal> to run GRUB in text mode.
|
|
|
|
|
'';
|
2009-09-29 11:50:38 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
configurationLimit = mkOption {
|
|
|
|
|
default = 100;
|
|
|
|
|
example = 120;
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.int;
|
2009-10-13 23:39:23 +02:00
|
|
|
|
description = ''
|
2009-09-29 11:50:38 +02:00
|
|
|
|
Maximum of configurations in boot menu. GRUB has problems when
|
|
|
|
|
there are too many entries.
|
2009-10-13 23:39:23 +02:00
|
|
|
|
'';
|
2009-09-29 11:50:38 +02:00
|
|
|
|
};
|
2009-01-02 17:07:34 +01:00
|
|
|
|
|
2009-09-29 11:50:38 +02:00
|
|
|
|
copyKernels = mkOption {
|
|
|
|
|
default = false;
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.bool;
|
2009-10-13 23:39:23 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Whether the GRUB menu builder should copy kernels and initial
|
2009-12-16 19:57:02 +01:00
|
|
|
|
ramdisks to /boot. This is done automatically if /boot is
|
|
|
|
|
on a different partition than /.
|
2009-10-13 23:39:23 +02:00
|
|
|
|
'';
|
2009-09-29 11:50:38 +02:00
|
|
|
|
};
|
2009-10-13 23:39:23 +02:00
|
|
|
|
|
2009-12-11 01:51:07 +01:00
|
|
|
|
timeout = mkOption {
|
2015-01-14 20:35:54 +01:00
|
|
|
|
default = if (config.boot.loader.timeout != null) then config.boot.loader.timeout else -1;
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.int;
|
2009-12-11 01:51:07 +01:00
|
|
|
|
description = ''
|
2011-09-14 20:20:50 +02:00
|
|
|
|
Timeout (in seconds) until GRUB boots the default menu item.
|
2009-12-11 01:51:07 +01:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
default = mkOption {
|
2009-12-15 19:21:55 +01:00
|
|
|
|
default = 0;
|
2013-10-07 11:05:33 +02:00
|
|
|
|
type = types.int;
|
2009-12-11 01:51:07 +01:00
|
|
|
|
description = ''
|
2009-12-15 19:21:55 +01:00
|
|
|
|
Index of the default menu item to be booted.
|
2009-12-11 01:51:07 +01:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-31 18:18:13 +02:00
|
|
|
|
fsIdentifier = mkOption {
|
|
|
|
|
default = "uuid";
|
|
|
|
|
type = types.addCheck types.str
|
|
|
|
|
(type: type == "uuid" || type == "label" || type == "provided");
|
2014-04-09 20:27:18 +02:00
|
|
|
|
description = ''
|
2014-08-31 18:18:13 +02:00
|
|
|
|
Determines how grub will identify devices when generating the
|
|
|
|
|
configuration file. A value of uuid / label signifies that grub
|
|
|
|
|
will always resolve the uuid or label of the device before using
|
|
|
|
|
it in the configuration. A value of provided means that grub will
|
|
|
|
|
use the device name as show in <command>df</command> or
|
|
|
|
|
<command>mount</command>. Note, zfs zpools / datasets are ignored
|
|
|
|
|
and will always be mounted using their labels.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
zfsSupport = mkOption {
|
|
|
|
|
default = false;
|
|
|
|
|
type = types.bool;
|
|
|
|
|
description = ''
|
|
|
|
|
Whether grub should be build against libzfs.
|
2015-01-14 10:30:57 +01:00
|
|
|
|
ZFS support is only available for GRUB v2.
|
|
|
|
|
This option is ignored for GRUB v1.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
efiSupport = mkOption {
|
|
|
|
|
default = false;
|
|
|
|
|
type = types.bool;
|
|
|
|
|
description = ''
|
|
|
|
|
Whether grub should be build with EFI support.
|
|
|
|
|
EFI support is only available for GRUB v2.
|
|
|
|
|
This option is ignored for GRUB v1.
|
2014-04-09 20:27:18 +02:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-21 20:41:46 +02:00
|
|
|
|
enableCryptodisk = mkOption {
|
|
|
|
|
default = false;
|
|
|
|
|
type = types.bool;
|
|
|
|
|
description = ''
|
|
|
|
|
Enable support for encrypted partitions. Grub should automatically
|
|
|
|
|
unlock the correct encrypted partition and look for filesystems.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2009-01-02 17:07:34 +01:00
|
|
|
|
};
|
Making modular my previous changes for armv5tel. I updated the way to use
grub. Its options are no more inside 'boot', but inside 'boot.loader.grub'.
I added a new bootloader configuration for nixos, generationsDir. It creates
/boot/default/{init,initrd,kernel,system} symlinks, and the same for the generations
in /boot/system-$gen/{init,initrd,kernel,system}.
I can program the u-boot loader to load /boot/default files always, and have
a minimal nixos boot loader installer functionality. Additionally, I can refer
to the other system generations easily, with a simple 'ls' in /boot.
svn path=/nixos/trunk/; revision=17460
2009-09-27 23:51:37 +02:00
|
|
|
|
|
2009-01-02 17:07:34 +01:00
|
|
|
|
};
|
2011-09-14 20:20:50 +02:00
|
|
|
|
|
2009-09-29 11:50:38 +02:00
|
|
|
|
|
|
|
|
|
###### implementation
|
2009-01-02 17:07:34 +01:00
|
|
|
|
|
2013-10-24 01:48:07 +02:00
|
|
|
|
config = mkMerge [
|
2011-09-14 20:20:50 +02:00
|
|
|
|
|
2013-10-24 01:48:07 +02:00
|
|
|
|
{ boot.loader.grub.splashImage = mkDefault (
|
|
|
|
|
if cfg.version == 1 then pkgs.fetchurl {
|
|
|
|
|
url = http://www.gnome-look.org/CONTENT/content-files/36909-soft-tux.xpm.gz;
|
|
|
|
|
sha256 = "14kqdx2lfqvh40h6fjjzqgff1mwk74dmbjvmqphi6azzra7z8d59";
|
|
|
|
|
}
|
|
|
|
|
# GRUB 1.97 doesn't support gzipped XPMs.
|
|
|
|
|
else ./winkler-gnu-blue-640x480.png);
|
|
|
|
|
}
|
2012-05-14 03:53:47 +02:00
|
|
|
|
|
2013-10-24 01:48:07 +02:00
|
|
|
|
(mkIf cfg.enable {
|
2013-10-23 20:06:39 +02:00
|
|
|
|
|
2013-10-24 01:48:07 +02:00
|
|
|
|
boot.loader.grub.devices = optional (cfg.device != "") cfg.device;
|
2013-10-17 13:30:49 +02:00
|
|
|
|
|
2013-10-24 01:48:07 +02:00
|
|
|
|
system.build.installBootLoader =
|
|
|
|
|
if cfg.devices == [] then
|
2013-10-28 17:24:14 +01:00
|
|
|
|
throw "You must set the option ‘boot.loader.grub.device’ to make the system bootable."
|
2013-10-24 01:48:07 +02:00
|
|
|
|
else
|
2015-01-14 10:30:57 +01:00
|
|
|
|
"PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX ListCompare ])} " +
|
2014-09-21 20:41:46 +02:00
|
|
|
|
(if cfg.enableCryptodisk then "GRUB_ENABLE_CRYPTODISK=y " else "") +
|
2013-10-24 01:48:07 +02:00
|
|
|
|
"${pkgs.perl}/bin/perl ${./install-grub.pl} ${grubConfig}";
|
Making modular my previous changes for armv5tel. I updated the way to use
grub. Its options are no more inside 'boot', but inside 'boot.loader.grub'.
I added a new bootloader configuration for nixos, generationsDir. It creates
/boot/default/{init,initrd,kernel,system} symlinks, and the same for the generations
in /boot/system-$gen/{init,initrd,kernel,system}.
I can program the u-boot loader to load /boot/default files always, and have
a minimal nixos boot loader installer functionality. Additionally, I can refer
to the other system generations easily, with a simple 'ls' in /boot.
svn path=/nixos/trunk/; revision=17460
2009-09-27 23:51:37 +02:00
|
|
|
|
|
2013-10-24 01:48:07 +02:00
|
|
|
|
system.build.grub = grub;
|
2009-10-13 23:39:18 +02:00
|
|
|
|
|
2013-10-24 01:48:07 +02:00
|
|
|
|
# Common attribute for boot loaders so only one of them can be
|
|
|
|
|
# set at once.
|
|
|
|
|
system.boot.loader.id = "grub";
|
2009-10-13 23:39:18 +02:00
|
|
|
|
|
2013-10-30 14:18:41 +01:00
|
|
|
|
environment.systemPackages = optional (grub != null) grub;
|
2013-10-02 12:29:07 +02:00
|
|
|
|
|
2013-10-24 01:48:07 +02:00
|
|
|
|
boot.loader.grub.extraPrepareConfig =
|
|
|
|
|
concatStrings (mapAttrsToList (n: v: ''
|
|
|
|
|
${pkgs.coreutils}/bin/cp -pf "${v}" "/boot/${n}"
|
|
|
|
|
'') config.boot.loader.grub.extraFiles);
|
|
|
|
|
|
2014-08-31 18:18:13 +02:00
|
|
|
|
assertions = [{ assertion = !cfg.zfsSupport || cfg.version == 2;
|
2014-09-04 18:15:59 +02:00
|
|
|
|
message = "Only grub version 2 provides zfs support";}]
|
|
|
|
|
++ flip map cfg.devices (dev: {
|
2014-09-08 12:00:34 +02:00
|
|
|
|
assertion = dev == "nodev" || hasPrefix "/" dev;
|
2014-09-04 18:15:59 +02:00
|
|
|
|
message = "Grub devices must be absolute paths, not ${dev}";
|
|
|
|
|
});
|
2014-08-31 18:18:13 +02:00
|
|
|
|
|
2013-10-24 01:48:07 +02:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
];
|
2011-09-14 20:20:50 +02:00
|
|
|
|
|
2009-01-02 17:07:34 +01:00
|
|
|
|
}
|