From 8d092270d28d82aa5623bcde55a2ee85129ac1f1 Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sun, 26 Oct 2014 21:29:04 +0100 Subject: nixos: iso-image: use syslinux bootloader for USB booting support This changes the bootloader for iso generation from Grub to syslinux. In addition this adds USB booting support, so that "dd" can be used to burn the generated ISO to USB thumbdrives instead of needing applications like UnetBootin. --- .../installer/cd-dvd/installation-cd-base.nix | 3 + nixos/modules/installer/cd-dvd/iso-image.nix | 132 ++++++++++----------- 2 files changed, 66 insertions(+), 69 deletions(-) (limited to 'nixos/modules') 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"; -- cgit 1.4.1 From a12ddc1964d0c66d81e9e5f05aedaec55bd3a1cd Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sun, 16 Nov 2014 20:11:56 +0100 Subject: nixos: iso-image: use generic boot-loader timeout Syslinux uses different values than grub for timeout. It uses 1/10 seconds as its unit and it uses 0 to disable timeouts. In response to PR #5772. --- nixos/modules/installer/cd-dvd/iso-image.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'nixos/modules') diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index 57e1601a87b4..8db7ae366f17 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -7,14 +7,25 @@ with lib; let + # Timeout in syslinux is in units of 1/10 of a second. + # 0 is used to disable timeouts. + syslinuxTimeout = if config.boot.loader.timeout == null then + 0 + else + max (config.boot.loader.timeout * 10) 1; + + + max = x: y: if x > y then x else y; # The configuration file for syslinux. baseIsolinuxCfg = '' SERIAL 0 38400 + TIMEOUT ${builtins.toString syslinuxTimeout} UI vesamenu.c32 MENU TITLE NixOS MENU BACKGROUND /isolinux/background.png + DEFAULT boot LABEL boot MENU LABEL Boot NixOS @@ -47,7 +58,7 @@ let echo "initrd /boot/initrd" >> $out/loader/entries/nixos-livecd.conf echo "options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" >> $out/loader/entries/nixos-livecd.conf echo "default nixos-livecd" > $out/loader/loader.conf - echo "timeout 5" >> $out/loader/loader.conf + echo "timeout ${builtins.toString config.boot.loader.gummiboot.timeout}" >> $out/loader/loader.conf ''; efiImg = pkgs.runCommand "efi-image_eltorito" { buildInputs = [ pkgs.mtools ]; } @@ -280,6 +291,8 @@ in } ]; + boot.loader.timeout = 10; + # Create the ISO image. system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({ inherit (pkgs) stdenv perl pathsFromGraph xorriso syslinux; -- cgit 1.4.1 From af68f2400365d830131acf5fb0f3e2c8cbad65a7 Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sun, 16 Nov 2014 20:13:11 +0100 Subject: nixos: iso-image: solve UNetbootin compatiblity There are a number of hidden restrictions on the syslinux configuration file that come into play when UNetbootin compatiblity is desired. With this commit these are documented. --- nixos/modules/installer/cd-dvd/iso-image.nix | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'nixos/modules') diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index 8db7ae366f17..2b125fa8bc15 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -18,6 +18,18 @@ let max = x: y: if x > y then x else y; # The configuration file for syslinux. + + # Notes on syslinux configuration and UNetbootin compatiblity: + # * Do not use '/syslinux/syslinux.cfg' as the path for this + # configuration. UNetbootin will not parse the file and use it as-is. + # This results in a broken configuration if the partition label does + # not match the specified config.isoImage.volumeID. For this reason + # we're using '/isolinux/isolinux.cfg'. + # * Use APPEND instead of adding command-line arguments directly after + # the LINUX entries. + # * COM32 entries (chainload, reboot, poweroff) are not recognized. They + # result in incorrect boot entries. + baseIsolinuxCfg = '' SERIAL 0 38400 @@ -28,8 +40,9 @@ let DEFAULT boot LABEL boot - MENU LABEL Boot NixOS - LINUX /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} + MENU LABEL NixOS ${config.system.nixosVersion} Installer + LINUX /boot/bzImage + APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} INITRD /boot/initrd LABEL chain -- cgit 1.4.1 From 9ff9949896c7ff0307ea60dc8d25de340860bfc4 Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Sun, 16 Nov 2014 20:13:49 +0100 Subject: nixos: iso-image: removed com32 entries from syslinux menu These entries result in incorrect entries when UNetbootin writes the image to an USB disk. --- nixos/modules/installer/cd-dvd/iso-image.nix | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'nixos/modules') diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index 2b125fa8bc15..c41d22ffd0d8 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -44,19 +44,6 @@ let LINUX /boot/bzImage APPEND 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); -- cgit 1.4.1 From f0fd1c9bcfd745d3576dc8ca1357ad458a522fc2 Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Wed, 21 Jan 2015 14:00:18 +0100 Subject: nixos: iso-image: use memtest86 params in syslinux See also #6593. --- nixos/modules/installer/cd-dvd/iso-image.nix | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'nixos/modules') diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index c41d22ffd0d8..87e8fabe2730 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -46,6 +46,13 @@ let INITRD /boot/initrd ''; + isolinuxMemtest86Entry = '' + LABEL memtest + MENU LABEL Memtest86+ + LINUX /boot/memtest.bin + APPEND ${toString config.boot.loader.grub.memtest86.params} + ''; + isolinuxCfg = baseIsolinuxCfg + (optionalString config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry); # The efi boot image @@ -289,6 +296,10 @@ in { source = "${efiDir}/loader"; target = "/loader"; } + ] ++ optionals config.boot.loader.grub.memtest86.enable [ + { source = "${pkgs.memtest86plus}/memtest.bin"; + target = "/boot/memtest.bin"; + } ]; boot.loader.timeout = 10; -- cgit 1.4.1 From 58112832a795337dfb3c205307ab9fe2c9280759 Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Tue, 3 Feb 2015 23:23:41 +0100 Subject: nixos: iso-image: use label "EFIBOOT" for efi.img --- nixos/modules/installer/cd-dvd/iso-image.nix | 1 + 1 file changed, 1 insertion(+) (limited to 'nixos/modules') diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index 87e8fabe2730..4fa2a2f6d52c 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -73,6 +73,7 @@ let #Let's hope 15M is enough dd bs=2048 count=7680 if=/dev/zero of="$out" ${pkgs.dosfstools}/sbin/mkfs.vfat "$out" + mlabel -i "$out" ::EFIBOOT mcopy -svi "$out" ${efiDir}/* :: mmd -i "$out" boot mcopy -v -i "$out" \ -- cgit 1.4.1