diff options
-rw-r--r-- | nixos/lib/make-iso9660-image.nix | 13 | ||||
-rw-r--r-- | nixos/lib/make-iso9660-image.sh | 48 | ||||
-rw-r--r-- | nixos/modules/installer/cd-dvd/iso-image.nix | 132 |
3 files changed, 112 insertions, 81 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/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index 22f31c460802..f387c64cb9c9 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -8,45 +8,37 @@ with lib; let - # The Grub image. - grubImage = pkgs.runCommand "grub_eltorito" {} + # The configuration file for syslinux. + isolinuxCfg = '' - ${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 ''; - # 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 +144,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 +174,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 @@ -213,7 +221,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" ]; @@ -233,15 +241,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"; @@ -249,51 +254,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"; |