2009-06-05 13:35:27 +00:00
|
|
|
# This module creates a bootable ISO image containing the given NixOS
|
|
|
|
# configuration. The derivation for the ISO image will be placed in
|
|
|
|
# config.system.build.isoImage.
|
|
|
|
|
2009-11-14 16:12:02 +00:00
|
|
|
{ config, pkgs, ... }:
|
|
|
|
|
|
|
|
with pkgs.lib;
|
2009-06-05 13:35:27 +00:00
|
|
|
|
|
|
|
let
|
2009-06-09 12:01:31 +00:00
|
|
|
|
|
|
|
options = {
|
|
|
|
|
2009-11-14 16:12:02 +00:00
|
|
|
isoImage.isoName = mkOption {
|
2011-04-20 10:48:52 +00:00
|
|
|
default = "${config.isoImage.isoName}.iso";
|
2009-06-09 15:23:03 +00:00
|
|
|
description = ''
|
|
|
|
Name of the generated ISO image file.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2011-04-20 10:48:52 +00:00
|
|
|
isoImage.isoBaseName = mkOption {
|
|
|
|
default = "nixos";
|
|
|
|
description = ''
|
|
|
|
Prefix of the name of the generated ISO image file.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-11-14 16:12:02 +00:00
|
|
|
isoImage.compressImage = mkOption {
|
2009-06-09 15:23:03 +00:00
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Whether the ISO image should be compressed using
|
|
|
|
<command>bzip2</command>.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-11-14 16:12:02 +00:00
|
|
|
isoImage.volumeID = mkOption {
|
2009-06-09 15:23:03 +00:00
|
|
|
default = "NIXOS_BOOT_CD";
|
|
|
|
description = ''
|
|
|
|
Specifies the label or volume ID of the generated ISO image.
|
|
|
|
Note that the label is used by stage 1 of the boot process to
|
|
|
|
mount the CD, so it should be reasonably distinctive.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-11-14 16:12:02 +00:00
|
|
|
isoImage.contents = mkOption {
|
2009-06-09 12:01:31 +00:00
|
|
|
example =
|
|
|
|
[ { source = pkgs.memtest86 + "/memtest.bin";
|
|
|
|
target = "boot/memtest.bin";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
description = ''
|
2009-06-09 13:27:50 +00:00
|
|
|
This option lists files to be copied to fixed locations in the
|
|
|
|
generated ISO image.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-11-14 16:12:02 +00:00
|
|
|
isoImage.storeContents = mkOption {
|
2009-06-10 16:29:48 +00:00
|
|
|
example = [pkgs.stdenv];
|
2009-06-09 13:27:50 +00:00
|
|
|
description = ''
|
|
|
|
This option lists additional derivations to be included in the
|
|
|
|
Nix store in the generated ISO image.
|
2009-06-09 12:01:31 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2010-08-29 12:11:31 +00:00
|
|
|
isoImage.includeSystemBuildDependencies = mkOption {
|
|
|
|
default = false;
|
|
|
|
example = true;
|
|
|
|
description = ''
|
|
|
|
Set this option to include all the needed sources etc in the
|
|
|
|
image. It significantly increases image size. Use that when
|
|
|
|
you want to be able to keep all the sources needed to build your
|
|
|
|
system or when you are going to install the system on a computer
|
|
|
|
with slow on non-existent network connection.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2012-03-16 05:37:24 +00:00
|
|
|
isoImage.makeEfiBootable = mkOption {
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Whether the ISO image should be an efi-bootable volume
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-06-09 12:01:31 +00:00
|
|
|
};
|
|
|
|
|
2009-06-05 13:35:27 +00:00
|
|
|
|
2009-11-10 21:42:38 +00:00
|
|
|
# The Grub image.
|
|
|
|
grubImage = pkgs.runCommand "grub_eltorito" {}
|
|
|
|
''
|
2011-03-09 16:26:03 +00:00
|
|
|
${pkgs.grub2}/bin/grub-mkimage -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain gfxterm vbe png jpeg
|
2009-11-10 21:42:38 +00:00
|
|
|
cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out
|
|
|
|
''; # */
|
|
|
|
|
|
|
|
|
2009-06-05 13:35:27 +00:00
|
|
|
# The configuration file for Grub.
|
2011-09-14 18:20:50 +00:00
|
|
|
grubCfg =
|
2009-06-05 13:35:27 +00:00
|
|
|
''
|
2009-12-11 00:51:07 +00:00
|
|
|
set default=${builtins.toString config.boot.loader.grub.default}
|
|
|
|
set timeout=${builtins.toString config.boot.loader.grub.timeout}
|
2009-11-13 16:45:41 +00:00
|
|
|
|
|
|
|
if loadfont /boot/grub/unicode.pf2; then
|
|
|
|
set gfxmode=640x480
|
|
|
|
insmod gfxterm
|
|
|
|
insmod vbe
|
2010-07-13 11:48:40 +00:00
|
|
|
terminal_output gfxterm
|
2009-11-13 16:45:41 +00:00
|
|
|
|
|
|
|
insmod png
|
|
|
|
if background_image /boot/grub/splash.png; then
|
|
|
|
set color_normal=white/black
|
|
|
|
set color_highlight=black/white
|
|
|
|
else
|
|
|
|
set menu_color_normal=cyan/blue
|
|
|
|
set menu_color_highlight=white/blue
|
|
|
|
fi
|
2011-09-14 18:20:50 +00:00
|
|
|
|
2009-11-13 16:45:41 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
${config.boot.loader.grub.extraEntries}
|
2009-06-05 13:35:27 +00:00
|
|
|
'';
|
2011-09-14 18:20:50 +00:00
|
|
|
|
2012-03-16 05:37:24 +00:00
|
|
|
|
|
|
|
# The boot params for the efi boot stub
|
|
|
|
bootParams = pkgs.runCommand "boot-params_eltorito" {}
|
|
|
|
''
|
|
|
|
echo "\\boot\\bzImage initrd=\\boot\\initrd init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" | iconv -f utf-8 -t UCS-2 > $out
|
|
|
|
'';
|
|
|
|
|
|
|
|
targetArch = if pkgs.stdenv.isi686 then
|
|
|
|
"IA32"
|
|
|
|
else if pkgs.stdenv.isx86_64 then
|
|
|
|
"x64"
|
|
|
|
else
|
|
|
|
throw "Unsupported architecture";
|
|
|
|
|
2009-06-05 13:35:27 +00:00
|
|
|
in
|
|
|
|
|
|
|
|
{
|
2009-06-09 12:01:31 +00:00
|
|
|
require = options;
|
|
|
|
|
2009-11-13 16:45:41 +00:00
|
|
|
boot.loader.grub.version = 2;
|
|
|
|
|
2009-11-14 16:12:02 +00:00
|
|
|
# Don't build the GRUB menu builder script, since we don't need it
|
|
|
|
# here and it causes a cyclic dependency.
|
|
|
|
boot.loader.grub.enable = false;
|
|
|
|
|
|
|
|
# !!! Hack - attributes expected by other modules.
|
|
|
|
system.build.menuBuilder = "true";
|
2010-02-18 11:35:39 +00:00
|
|
|
system.boot.loader.kernelFile = "bzImage";
|
2009-11-14 16:12:02 +00:00
|
|
|
environment.systemPackages = [ pkgs.grub2 ];
|
|
|
|
|
2010-08-07 14:16:18 +00:00
|
|
|
# In stage 1 of the boot, mount the CD as the root FS by label so
|
|
|
|
# that we don't need to know its device. We pass the label of the
|
|
|
|
# root filesystem on the kernel command line, rather than in
|
|
|
|
# `fileSystems' below. This allows CD-to-USB converters such as
|
|
|
|
# UNetbootin to rewrite the kernel command line to pass the label or
|
|
|
|
# UUID of the USB stick. It would be nicer to write
|
|
|
|
# `root=/dev/disk/by-label/...' here, but UNetbootin doesn't
|
|
|
|
# recognise that.
|
|
|
|
boot.kernelParams = [ "root=LABEL=${config.isoImage.volumeID}" ];
|
|
|
|
|
|
|
|
# Note that /dev/root is a symlink to the actual root device
|
|
|
|
# specified on the kernel command line, created in the stage 1 init
|
|
|
|
# script.
|
2009-06-05 13:35:27 +00:00
|
|
|
fileSystems =
|
|
|
|
[ { mountPoint = "/";
|
2010-08-07 14:16:18 +00:00
|
|
|
device = "/dev/root";
|
2009-06-05 13:35:27 +00:00
|
|
|
}
|
2011-10-30 15:19:58 +00:00
|
|
|
{ mountPoint = "/nix/store";
|
2009-06-10 16:29:48 +00:00
|
|
|
fsType = "squashfs";
|
|
|
|
device = "/nix-store.squashfs";
|
|
|
|
options = "loop";
|
|
|
|
neededForBoot = true;
|
|
|
|
}
|
2009-06-05 13:35:27 +00:00
|
|
|
];
|
|
|
|
|
2009-06-10 16:29:48 +00:00
|
|
|
# We need squashfs in the initrd to mount the compressed Nix store,
|
|
|
|
# and aufs to make the root filesystem appear writable.
|
2009-12-15 14:05:01 +00:00
|
|
|
boot.extraModulePackages =
|
2011-11-08 15:12:11 +00:00
|
|
|
if config.boot.kernelPackages.aufs == null then
|
|
|
|
abort "This kernel doesn't have aufs enabled"
|
|
|
|
else
|
|
|
|
[ config.boot.kernelPackages.aufs ];
|
2011-09-14 18:20:50 +00:00
|
|
|
|
2010-01-03 16:29:17 +00:00
|
|
|
boot.initrd.availableKernelModules = [ "aufs" "squashfs" "iso9660" ];
|
2009-06-05 13:35:27 +00:00
|
|
|
|
2010-01-03 16:29:17 +00:00
|
|
|
boot.initrd.kernelModules = [ "loop" ];
|
2010-01-09 15:13:06 +00:00
|
|
|
|
|
|
|
# In stage 1, mount a tmpfs on top of / (the ISO image) and
|
2011-10-30 15:19:58 +00:00
|
|
|
# /nix/store (the squashfs image) to make this a live CD.
|
2010-01-09 15:13:06 +00:00
|
|
|
boot.initrd.postMountCommands =
|
|
|
|
''
|
|
|
|
mkdir /mnt-root-tmpfs
|
|
|
|
mount -t tmpfs -o "mode=755" none /mnt-root-tmpfs
|
|
|
|
mkdir /mnt-root-union
|
|
|
|
mount -t aufs -o dirs=/mnt-root-tmpfs=rw:$targetRoot=ro none /mnt-root-union
|
|
|
|
targetRoot=/mnt-root-union
|
|
|
|
|
|
|
|
mkdir /mnt-store-tmpfs
|
|
|
|
mount -t tmpfs -o "mode=755" none /mnt-store-tmpfs
|
2011-10-30 15:19:58 +00:00
|
|
|
mkdir -p $targetRoot/nix/store
|
|
|
|
mount -t aufs -o dirs=/mnt-store-tmpfs=rw:/mnt-root/nix/store=ro none /mnt-root-union/nix/store
|
2010-01-09 15:13:06 +00:00
|
|
|
'';
|
2009-06-05 13:35:27 +00:00
|
|
|
|
2009-06-10 16:29:48 +00:00
|
|
|
# Closures to be copied to the Nix store on the CD, namely the init
|
|
|
|
# script and the top-level system configuration directory.
|
|
|
|
isoImage.storeContents =
|
2011-09-14 18:20:50 +00:00
|
|
|
[ config.system.build.toplevel ] ++
|
2010-09-13 22:10:25 +00:00
|
|
|
optional config.isoImage.includeSystemBuildDependencies
|
|
|
|
config.system.build.toplevel.drvPath;
|
2009-06-10 16:29:48 +00:00
|
|
|
|
|
|
|
# Create the squashfs image that contains the Nix store.
|
|
|
|
system.build.squashfsStore = import ../../../lib/make-squashfs.nix {
|
|
|
|
inherit (pkgs) stdenv squashfsTools perl pathsFromGraph;
|
|
|
|
storeContents = config.isoImage.storeContents;
|
|
|
|
};
|
|
|
|
|
2009-06-09 12:01:31 +00:00
|
|
|
# Individual files to be included on the CD, outside of the Nix
|
|
|
|
# store on the CD.
|
|
|
|
isoImage.contents =
|
2009-11-10 21:42:38 +00:00
|
|
|
[ { source = grubImage;
|
|
|
|
target = "/boot/grub/grub_eltorito";
|
2009-06-09 12:01:31 +00:00
|
|
|
}
|
2009-11-10 21:42:38 +00:00
|
|
|
{ source = pkgs.writeText "grub.cfg" grubCfg;
|
|
|
|
target = "/boot/grub/grub.cfg";
|
2009-06-09 12:01:31 +00:00
|
|
|
}
|
2010-02-18 11:35:39 +00:00
|
|
|
{ source = config.boot.kernelPackages.kernel + "/bzImage";
|
|
|
|
target = "/boot/bzImage";
|
2009-06-09 12:01:31 +00:00
|
|
|
}
|
|
|
|
{ source = config.system.build.initialRamdisk + "/initrd";
|
|
|
|
target = "/boot/initrd";
|
|
|
|
}
|
2009-11-13 16:45:41 +00:00
|
|
|
{ source = "${pkgs.grub2}/share/grub/unicode.pf2";
|
|
|
|
target = "/boot/grub/unicode.pf2";
|
|
|
|
}
|
|
|
|
{ source = config.boot.loader.grub.splashImage;
|
|
|
|
target = "/boot/grub/splash.png";
|
2009-06-09 12:01:31 +00:00
|
|
|
}
|
2009-06-10 16:29:48 +00:00
|
|
|
{ source = config.system.build.squashfsStore;
|
|
|
|
target = "/nix-store.squashfs";
|
2009-06-09 13:27:50 +00:00
|
|
|
}
|
2009-06-10 16:29:48 +00:00
|
|
|
{ # Quick hack: need a mount point for the store.
|
|
|
|
source = pkgs.runCommand "empty" {} "ensureDir $out";
|
2011-10-30 15:19:58 +00:00
|
|
|
target = "/nix/store";
|
2009-06-09 13:27:50 +00:00
|
|
|
}
|
2012-03-16 05:37:24 +00:00
|
|
|
] ++ pkgs.stdenv.lib.optionals config.isoImage.makeEfiBootable [
|
|
|
|
{ source = bootParams;
|
|
|
|
target = "/efi/nixos/boot-params";
|
|
|
|
}
|
|
|
|
{ source = "${pkgs.NixosBootPkg}/*/NixosBoot.efi";
|
|
|
|
target = "/efi/boot/boot${targetArch}.efi";
|
|
|
|
}
|
2009-06-09 13:27:50 +00:00
|
|
|
];
|
|
|
|
|
2009-06-09 12:01:31 +00:00
|
|
|
# The Grub menu.
|
2009-11-13 16:45:41 +00:00
|
|
|
boot.loader.grub.extraEntries =
|
2009-06-09 12:01:31 +00:00
|
|
|
''
|
2009-11-10 21:42:38 +00:00
|
|
|
menuentry "NixOS Installer / Rescue" {
|
2010-09-13 22:10:25 +00:00
|
|
|
linux /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
|
2009-06-09 12:01:31 +00:00
|
|
|
initrd /boot/initrd
|
2009-11-10 21:42:38 +00:00
|
|
|
}
|
2010-01-06 12:24:20 +00:00
|
|
|
|
|
|
|
menuentry "Boot from hard disk" {
|
|
|
|
set root=(hd0)
|
|
|
|
chainloader +1
|
|
|
|
}
|
2009-06-09 12:01:31 +00:00
|
|
|
'';
|
2011-09-14 18:20:50 +00:00
|
|
|
|
2009-12-11 00:51:07 +00:00
|
|
|
boot.loader.grub.timeout = 10;
|
2009-06-09 12:01:31 +00:00
|
|
|
|
2009-06-05 13:35:27 +00:00
|
|
|
# Create the ISO image.
|
2012-03-16 05:37:24 +00:00
|
|
|
system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({
|
2009-06-05 13:35:27 +00:00
|
|
|
inherit (pkgs) stdenv perl cdrkit pathsFromGraph;
|
2011-09-14 18:20:50 +00:00
|
|
|
|
2009-06-10 16:29:48 +00:00
|
|
|
inherit (config.isoImage) isoName compressImage volumeID contents;
|
2009-06-05 13:35:27 +00:00
|
|
|
|
|
|
|
bootable = true;
|
2009-11-10 21:42:38 +00:00
|
|
|
bootImage = "/boot/grub/grub_eltorito";
|
2012-03-16 05:37:24 +00:00
|
|
|
} // pkgs.stdenv.lib.optionalAttrs config.isoImage.makeEfiBootable {
|
|
|
|
efiBootable = true;
|
|
|
|
efiBootImage = "efi/boot/boot${targetArch}.efi";
|
|
|
|
});
|
2009-06-05 16:02:58 +00:00
|
|
|
|
|
|
|
boot.postBootCommands =
|
|
|
|
''
|
2009-06-10 16:29:48 +00:00
|
|
|
# After booting, register the contents of the Nix store on the
|
|
|
|
# CD in the Nix database in the tmpfs.
|
2011-10-30 15:19:58 +00:00
|
|
|
${config.environment.nix}/bin/nix-store --load-db < /nix/store/nix-path-registration
|
2009-06-10 12:51:16 +00:00
|
|
|
|
|
|
|
# nixos-rebuild also requires a "system" profile and an
|
|
|
|
# /etc/NIXOS tag.
|
|
|
|
touch /etc/NIXOS
|
2011-10-30 15:19:58 +00:00
|
|
|
${config.environment.nix}/bin/nix-env -p /nix/var/nix/profiles/system --set /var/run/current-system
|
2009-06-05 16:02:58 +00:00
|
|
|
'';
|
2012-03-09 16:17:37 +00:00
|
|
|
|
|
|
|
# Add vfat support to the initrd to enable people to copy the
|
|
|
|
# contents of the CD to a bootable USB stick.
|
|
|
|
boot.initrd.supportedFilesystems = [ "vfat" ];
|
|
|
|
|
2009-06-05 13:35:27 +00:00
|
|
|
}
|