summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nixos/lib/make-iso9660-image.nix13
-rw-r--r--nixos/lib/make-iso9660-image.sh48
-rw-r--r--nixos/modules/installer/cd-dvd/installation-cd-base.nix3
-rw-r--r--nixos/modules/installer/cd-dvd/iso-image.nix132
4 files changed, 116 insertions, 80 deletions
diff --git a/nixos/lib/make-iso9660-image.nix b/nixos/lib/make-iso9660-image.nix
index 5ad546e9534d..b2409c6006bc 100644
--- a/nixos/lib/make-iso9660-image.nix
+++ b/nixos/lib/make-iso9660-image.nix
@@ -1,4 +1,4 @@
-{ stdenv, perl, cdrkit, pathsFromGraph
+{ stdenv, perl, pathsFromGraph, xorriso, syslinux
, # The file name of the resulting ISO image.
isoName ? "cd.iso"
@@ -22,12 +22,18 @@
, # Whether this should be an efi-bootable El-Torito CD.
efiBootable ? false
+, # Wheter this should be an hybrid CD (bootable from USB as well as CD).
+ usbBootable ? false
+
, # The path (in the ISO file system) of the boot image.
bootImage ? ""
, # The path (in the ISO file system) of the efi boot image.
efiBootImage ? ""
+, # The path (outside the ISO file system) of the isohybrid-mbr image.
+ isohybridMbrImage ? ""
+
, # Whether to compress the resulting ISO image with bzip2.
compressImage ? false
@@ -38,13 +44,14 @@
assert bootable -> bootImage != "";
assert efiBootable -> efiBootImage != "";
+assert usbBootable -> isohybridMbrImage != "";
stdenv.mkDerivation {
name = "iso9660-image";
builder = ./make-iso9660-image.sh;
- buildInputs = [perl cdrkit];
+ buildInputs = [perl xorriso syslinux];
- inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable;
+ inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable isohybridMbrImage usbBootable;
# !!! should use XML.
sources = map (x: x.source) contents;
diff --git a/nixos/lib/make-iso9660-image.sh b/nixos/lib/make-iso9660-image.sh
index 675b5bb35148..c8522513aa23 100644
--- a/nixos/lib/make-iso9660-image.sh
+++ b/nixos/lib/make-iso9660-image.sh
@@ -31,11 +31,20 @@ if test -n "$bootable"; then
fi
done
- bootFlags="-b $bootImage -c .boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table"
+ isoBootFlags="-eltorito-boot ${bootImage}
+ -eltorito-catalog .boot.cat
+ -no-emul-boot -boot-load-size 4 -boot-info-table"
+fi
+
+if test -n "$usbBootable"; then
+ usbBootFlags="-isohybrid-mbr ${isohybridMbrImage}"
fi
if test -n "$efiBootable"; then
- bootFlags="$bootFlags -eltorito-alt-boot -e $efiBootImage -no-emul-boot"
+ efiBootFlags="-eltorito-alt-boot
+ -e $efiBootImage
+ -no-emul-boot
+ -isohybrid-gpt-basdat"
fi
touch pathlist
@@ -74,18 +83,41 @@ for ((n = 0; n < ${#objects[*]}; n++)); do
fi
done
-# !!! what does this do?
+# Escape filenames that contain '='.
+# TODO: Handle this properly. This fails for filenames
+# that contain multiple '=' symbols.
cat pathlist | sed -e 's/=\(.*\)=\(.*\)=/\\=\1=\2\\=/' | tee pathlist.safer
mkdir -p $out/iso
-genCommand="genisoimage -iso-level 4 -r -J $bootFlags -hide-rr-moved -graft-points -path-list pathlist.safer ${volumeID:+-V $volumeID}"
-if test -z "$compressImage"; then
- $genCommand -o $out/iso/$isoName
-else
- $genCommand | bzip2 > $out/iso/$isoName.bz2
+
+xorriso="xorriso
+ -as mkisofs
+ -iso-level 3
+ -volid ${volumeID}
+ -appid nixos
+ -publisher nixos
+ -graft-points
+ -full-iso9660-filenames
+ ${isoBootFlags}
+ ${usbBootFlags}
+ ${efiBootFlags}
+ -r
+ -path-list pathlist.safer
+ --sort-weight 0 /
+ --sort-weight 1 /isolinux" # Make sure isolinux is near the beginning of the ISO
+
+$xorriso -output $out/iso/$isoName
+
+if test -n "$usbBootable"; then
+ echo "Making image hybrid..."
+ isohybrid --uefi $out/iso/$isoName
fi
+if test -n "$compressImage"; then
+ echo "Compressing image..."
+ bzip2 $out/iso/$isoName
+fi
mkdir -p $out/nix-support
echo $system > $out/nix-support/system
diff --git a/nixos/modules/installer/cd-dvd/installation-cd-base.nix b/nixos/modules/installer/cd-dvd/installation-cd-base.nix
index b723a91e4f35..4896eee29084 100644
--- a/nixos/modules/installer/cd-dvd/installation-cd-base.nix
+++ b/nixos/modules/installer/cd-dvd/installation-cd-base.nix
@@ -36,6 +36,9 @@ with lib;
# EFI booting
isoImage.makeEfiBootable = true;
+ # USB booting
+ isoImage.makeUsbBootable = true;
+
# Add Memtest86+ to the CD.
boot.loader.grub.memtest86.enable = true;
diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix
index 39db7d9b8f72..57e1601a87b4 100644
--- a/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -8,45 +8,39 @@ with lib;
let
- # The Grub image.
- grubImage = pkgs.runCommand "grub_eltorito" {}
+ # The configuration file for syslinux.
+ baseIsolinuxCfg =
''
- ${pkgs.grub2}/bin/grub-mkimage -p /boot/grub -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain png jpeg echo gfxmenu reboot
- cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out
- ''; # */
-
-
- # The configuration file for Grub.
- grubCfg =
- ''
- set default=${builtins.toString config.boot.loader.grub.default}
- set timeout=${builtins.toString config.boot.loader.grub.timeout}
-
- if loadfont /boot/grub/unicode.pf2; then
- set gfxmode=640x480
- insmod gfxterm
- insmod vbe
- terminal_output gfxterm
-
- 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
-
- fi
-
- ${config.boot.loader.grub.extraEntries}
+ SERIAL 0 38400
+ UI vesamenu.c32
+ MENU TITLE NixOS
+ MENU BACKGROUND /isolinux/background.png
+
+ LABEL boot
+ MENU LABEL Boot NixOS
+ LINUX /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
+ INITRD /boot/initrd
+
+ LABEL chain
+ MENU LABEL Boot existing OS
+ COM32 chain.c32
+ APPEND hd0 0
+
+ LABEL reboot
+ MENU LABEL Reboot
+ COM32 reboot.c32
+
+ LABEL poweroff
+ MENU LABEL Power Off
+ COM32 poweroff.c32
'';
+ isolinuxCfg = baseIsolinuxCfg + (optionalString config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry);
# The efi boot image
efiDir = pkgs.runCommand "efi-directory" {} ''
- mkdir -p $out/efi/boot
- cp -v ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi $out/efi/boot/boot${targetArch}.efi
+ mkdir -p $out/EFI/boot
+ cp -v ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi $out/EFI/boot/boot${targetArch}.efi
mkdir -p $out/loader/entries
echo "title NixOS LiveCD" > $out/loader/entries/nixos-livecd.conf
echo "linux /boot/bzImage" >> $out/loader/entries/nixos-livecd.conf
@@ -152,6 +146,22 @@ in
'';
};
+ isoImage.makeUsbBootable = mkOption {
+ default = false;
+ description = ''
+ Whether the ISO image should be bootable from CD as well as USB.
+ '';
+ };
+
+ isoImage.splashImage = mkOption {
+ default = pkgs.fetchurl {
+ url = https://raw.githubusercontent.com/NixOS/nixos-artwork/5729ab16c6a5793c10a2913b5a1b3f59b91c36ee/ideas/grub-splash/grub-nixos-1.png;
+ sha256 = "43fd8ad5decf6c23c87e9026170a13588c2eba249d9013cb9f888da5e2002217";
+ };
+ description = ''
+ The splash image to use in the bootloader.
+ '';
+ };
};
@@ -166,7 +176,7 @@ in
# !!! Hack - attributes expected by other modules.
system.boot.loader.kernelFile = "bzImage";
- environment.systemPackages = [ pkgs.grub2 ];
+ environment.systemPackages = [ pkgs.grub2 pkgs.syslinux ];
# 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
@@ -216,7 +226,7 @@ in
options = "allow_other,cow,nonempty,chroot=/mnt-root,max_files=32768,hide_meta_files,dirs=/nix/.rw-store=rw:/nix/.ro-store=ro";
};
- boot.initrd.availableKernelModules = [ "squashfs" "iso9660" ];
+ boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "usb-storage" ];
boot.initrd.kernelModules = [ "loop" ];
@@ -236,15 +246,12 @@ in
# Individual files to be included on the CD, outside of the Nix
# store on the CD.
isoImage.contents =
- [ { source = grubImage;
- target = "/boot/grub/grub_eltorito";
- }
- { source = pkgs.substituteAll {
- name = "grub.cfg";
- src = pkgs.writeText "grub.cfg-in" grubCfg;
+ [ { source = pkgs.substituteAll {
+ name = "isolinux.cfg";
+ src = pkgs.writeText "isolinux.cfg-in" isolinuxCfg;
bootRoot = "/boot";
};
- target = "/boot/grub/grub.cfg";
+ target = "/isolinux/isolinux.cfg";
}
{ source = config.boot.kernelPackages.kernel + "/bzImage";
target = "/boot/bzImage";
@@ -252,51 +259,38 @@ in
{ source = config.system.build.initialRamdisk + "/initrd";
target = "/boot/initrd";
}
- { source = "${pkgs.grub2}/share/grub/unicode.pf2";
- target = "/boot/grub/unicode.pf2";
- }
- { source = config.boot.loader.grub.splashImage;
- target = "/boot/grub/splash.png";
- }
{ source = config.system.build.squashfsStore;
target = "/nix-store.squashfs";
}
+ { source = "${pkgs.syslinux}/share/syslinux";
+ target = "/isolinux";
+ }
+ { source = config.isoImage.splashImage;
+ target = "/isolinux/background.png";
+ }
] ++ optionals config.isoImage.makeEfiBootable [
{ source = efiImg;
target = "/boot/efi.img";
}
- { source = "${efiDir}/efi";
- target = "/efi";
+ { source = "${efiDir}/EFI";
+ target = "/EFI";
}
{ source = "${efiDir}/loader";
target = "/loader";
}
- ] ++ mapAttrsToList (n: v: { source = v; target = "/boot/${n}"; }) config.boot.loader.grub.extraFiles;
-
- # The Grub menu.
- boot.loader.grub.extraEntries =
- ''
- menuentry "NixOS ${config.system.nixosVersion} Installer" {
- linux /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
- initrd /boot/initrd
- }
-
- menuentry "Boot from hard disk" {
- set root=(hd0)
- chainloader +1
- }
- '';
-
- boot.loader.grub.timeout = 10;
+ ];
# Create the ISO image.
system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({
- inherit (pkgs) stdenv perl cdrkit pathsFromGraph;
+ inherit (pkgs) stdenv perl pathsFromGraph xorriso syslinux;
inherit (config.isoImage) isoName compressImage volumeID contents;
bootable = true;
- bootImage = "/boot/grub/grub_eltorito";
+ bootImage = "/isolinux/isolinux.bin";
+ } // optionalAttrs config.isoImage.makeUsbBootable {
+ usbBootable = true;
+ isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin";
} // optionalAttrs config.isoImage.makeEfiBootable {
efiBootable = true;
efiBootImage = "boot/efi.img";