diff options
Diffstat (limited to 'nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix')
-rw-r--r-- | nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix | 94 |
1 files changed, 78 insertions, 16 deletions
diff --git a/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix b/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix index 1418420afcd9..c2836b5a9a1b 100644 --- a/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix @@ -162,12 +162,14 @@ let isolinuxCfg = concatStringsSep "\n" ([ baseIsolinuxCfg ] ++ optional config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry); + refindBinary = if targetArch == "x64" || targetArch == "aa64" then "refind_${targetArch}.efi" else null; + # Setup instructions for rEFInd. refind = - if targetArch == "x64" then + if refindBinary != null then '' # Adds rEFInd to the ISO. - cp -v ${pkgs.refind}/share/refind/refind_x64.efi $out/EFI/boot/ + cp -v ${pkgs.refind}/share/refind/${refindBinary} $out/EFI/boot/ '' else "# No refind for ${targetArch}" @@ -180,13 +182,32 @@ let # Menu configuration # + # Search using a "marker file" + search --set=root --file /EFI/nixos-installer-image + insmod gfxterm insmod png set gfxpayload=keep + set gfxmode=${concatStringsSep "," [ + # GRUB will use the first valid mode listed here. + # `auto` will sometimes choose the smallest valid mode it detects. + # So instead we'll list a lot of possibly valid modes :/ + #"3840x2160" + #"2560x1440" + "1920x1080" + "1366x768" + "1280x720" + "1024x768" + "800x600" + "auto" + ]} # Fonts can be loaded? # (This font is assumed to always be provided as a fallback by NixOS) - if loadfont (hd0)/EFI/boot/unicode.pf2; then + if loadfont (\$root)/EFI/boot/unicode.pf2; then + set with_fonts=true + fi + if [ "\$textmode" != "true" -a "\$with_fonts" == "true" ]; then # Use graphical term, it can be either with background image or a theme. # input is "console", while output is "gfxterm". # This enables "serial" input and output only when possible. @@ -207,11 +228,11 @@ let ${ # When there is a theme configured, use it, otherwise use the background image. if config.isoImage.grubTheme != null then '' # Sets theme. - set theme=(hd0)/EFI/boot/grub-theme/theme.txt + set theme=(\$root)/EFI/boot/grub-theme/theme.txt # Load theme fonts - $(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (hd0)/EFI/boot/grub-theme/%P\n") + $(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (\$root)/EFI/boot/grub-theme/%P\n") '' else '' - if background_image (hd0)/EFI/boot/efi-background.png; then + if background_image (\$root)/EFI/boot/efi-background.png; then # Black background means transparent background when there # is a background image set... This seems undocumented :( set color_normal=black/black @@ -228,9 +249,15 @@ let # Notes about grub: # * Yes, the grubMenuCfg has to be repeated in all submenus. Otherwise you # will get white-on-black console-like text on sub-menus. *sigh* - efiDir = pkgs.runCommand "efi-directory" {} '' + efiDir = pkgs.runCommand "efi-directory" { + nativeBuildInputs = [ pkgs.buildPackages.grub2_efi ]; + strictDeps = true; + } '' mkdir -p $out/EFI/boot/ + # Add a marker so GRUB can find the filesystem. + touch $out/EFI/nixos-installer-image + # ALWAYS required modules. MODULES="fat iso9660 part_gpt part_msdos \ normal boot linux configfile loopback chain halt \ @@ -258,12 +285,14 @@ let # Make our own efi program, we can't rely on "grub-install" since it seems to # probe for devices, even with --skip-fs-probe. - ${grubPkgs.grub2_efi}/bin/grub-mkimage -o $out/EFI/boot/boot${targetArch}.efi -p /EFI/boot -O ${grubPkgs.grub2_efi.grubTarget} \ + grub-mkimage --directory=${grubPkgs.grub2_efi}/lib/grub/${grubPkgs.grub2_efi.grubTarget} -o $out/EFI/boot/boot${targetArch}.efi -p /EFI/boot -O ${grubPkgs.grub2_efi.grubTarget} \ $MODULES cp ${grubPkgs.grub2_efi}/share/grub/unicode.pf2 $out/EFI/boot/ cat <<EOF > $out/EFI/boot/grub.cfg + set with_fonts=false + set textmode=false # If you want to use serial for "terminal_*" commands, you need to set one up: # Example manual configuration: # → serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1 @@ -273,8 +302,28 @@ let export with_serial clear set timeout=10 + + # This message will only be viewable when "gfxterm" is not used. + echo "" + echo "Loading graphical boot menu..." + echo "" + echo "Press 't' to use the text boot menu on this console..." + echo "" + ${grubMenuCfg} + hiddenentry 'Text mode' --hotkey 't' { + loadfont (\$root)/EFI/boot/unicode.pf2 + set textmode=true + terminal_output gfxterm console + } + hiddenentry 'GUI mode' --hotkey 'g' { + $(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (\$root)/EFI/boot/grub-theme/%P\n") + set textmode=false + terminal_output gfxterm + } + + # If the parameter iso_path is set, append the findiso parameter to the kernel # line. We need this to allow the nixos iso to be booted from grub directly. if [ \''${iso_path} ] ; then @@ -337,11 +386,17 @@ let } } - menuentry 'rEFInd' --class refind { - # UUID is hard-coded in the derivation. + ${lib.optionalString (refindBinary != null) '' + # GRUB apparently cannot do "chainloader" operations on "CD". + if [ "\$root" != "cd0" ]; then + # Force root to be the FAT partition + # Otherwise it breaks rEFInd's boot search --set=root --no-floppy --fs-uuid 1234-5678 - chainloader (\$root)/EFI/boot/refind_x64.efi - } + menuentry 'rEFInd' --class refind { + chainloader (\$root)/EFI/boot/${refindBinary} + } + fi + ''} menuentry 'Firmware Setup' --class settings { fwsetup clear @@ -357,7 +412,10 @@ let ${refind} ''; - efiImg = pkgs.runCommand "efi-image_eltorito" { buildInputs = [ pkgs.mtools pkgs.libfaketime ]; } + efiImg = pkgs.runCommand "efi-image_eltorito" { + nativeBuildInputs = [ pkgs.buildPackages.mtools pkgs.buildPackages.libfaketime pkgs.buildPackages.dosfstools ]; + strictDeps = true; + } # Be careful about determinism: du --apparent-size, # dates (cp -p, touch, mcopy -m, faketime for label), IDs (mkfs.vfat -i) '' @@ -366,7 +424,9 @@ let mkdir ./boot cp -p "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}" \ "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}" ./boot/ - touch --date=@0 ./EFI ./boot + + # Rewrite dates for everything in the FS + find . -exec touch --date=2000-01-01 {} + usage_size=$(du -sb --apparent-size . | tr -cd '[:digit:]') # Make the image 110% as big as the files need to make up for FAT overhead @@ -377,10 +437,10 @@ let echo "Usage size: $usage_size" echo "Image size: $image_size" truncate --size=$image_size "$out" - ${pkgs.libfaketime}/bin/faketime "2000-01-01 00:00:00" ${pkgs.dosfstools}/sbin/mkfs.vfat -i 12345678 -n EFIBOOT "$out" + faketime "2000-01-01 00:00:00" mkfs.vfat -i 12345678 -n EFIBOOT "$out" mcopy -psvm -i "$out" ./EFI ./boot :: # Verify the FAT partition. - ${pkgs.dosfstools}/sbin/fsck.vfat -vn "$out" + fsck.vfat -vn "$out" ''; # */ # Name used by UEFI for architectures. @@ -389,6 +449,8 @@ let "ia32" else if pkgs.stdenv.isx86_64 then "x64" + else if pkgs.stdenv.isAarch32 then + "arm" else if pkgs.stdenv.isAarch64 then "aa64" else |