From d999e2544b65bfa52877da34a7b40316868a0a26 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Tue, 20 Apr 2021 01:29:52 -0400 Subject: [PATCH 1/5] grub2: Add support for hiddenentry The iso image will use this to allow switching to the text console. --- pkgs/tools/misc/grub/2.0x.nix | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkgs/tools/misc/grub/2.0x.nix b/pkgs/tools/misc/grub/2.0x.nix index 20f25187285..f36e64f57b2 100644 --- a/pkgs/tools/misc/grub/2.0x.nix +++ b/pkgs/tools/misc/grub/2.0x.nix @@ -1,6 +1,8 @@ { lib, stdenv, fetchgit, flex, bison, python3, autoconf, automake, gnulib, libtool , gettext, ncurses, libusb-compat-0_1, freetype, qemu, lvm2, unifont, pkg-config , buildPackages +, fetchpatch +, pkgsBuildBuild , nixosTests , fuse # only needed for grub-mount , runtimeShell @@ -55,6 +57,12 @@ stdenv.mkDerivation rec { patches = [ ./fix-bash-completion.patch + (fetchpatch { + name = "Add-hidden-menu-entries.patch"; + # https://lists.gnu.org/archive/html/grub-devel/2016-04/msg00089.html + url = "https://marc.info/?l=grub-devel&m=146193404929072&q=mbox"; + sha256 = "00wa1q5adiass6i0x7p98vynj9vsz1w0gn1g4dgz89v35mpyw2bi"; + }) ]; postPatch = if kbdcompSupport then '' From 20d0824b150492d4b484954c64aad9f24656c130 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Tue, 20 Apr 2021 01:32:42 -0400 Subject: [PATCH 2/5] iso-image: Fix grub file load location With U-Boot UEFI, (hd0) is not the USB drive, it is (cd0). Though, it turns out we never needed to prefix the path! --- nixos/modules/installer/cd-dvd/iso-image.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index 1418420afcd..e73bb883df5 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -186,7 +186,7 @@ let # 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 /EFI/boot/unicode.pf2; 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 +207,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=/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 /EFI/boot/grub-theme/%P\n") '' else '' - if background_image (hd0)/EFI/boot/efi-background.png; then + if background_image /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 From 189507a35d4fd5c88e1172aee0a410229e60ba86 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Tue, 20 Apr 2021 01:34:15 -0400 Subject: [PATCH 3/5] iso-image: Make graphical output work properly on AArch64 The serial output (but it's named console, not serial actually) causes issues on U-Boot's EFI, at the very least. This is inspired by OpenSUSE's approach: * https://build.opensuse.org/package/view_file/Base:System/grub2/grub2-SUSE-Add-the-t-hotkey.patch Where they add a hidden menu entry, which can be used to force the console output. The `echo` will be visible on the serial terminal (grub "console"), while the graphical interface is shown. Note that input in the serial terminal (grub "console") will continue controlling the graphical interface. Useful if you have an SBC connectedinto an HDMI monitor, but no keyboard connected to it. --- nixos/modules/installer/cd-dvd/iso-image.nix | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index e73bb883df5..b876e83e237 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -187,6 +187,9 @@ let # Fonts can be loaded? # (This font is assumed to always be provided as a fallback by NixOS) if loadfont /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. @@ -264,6 +267,8 @@ let cat < $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 +278,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 /EFI/boot/unicode.pf2 + set textmode=true + terminal_output gfxterm console + } + hiddenentry 'GUI mode' --hotkey 'g' { + $(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont /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 From 9413da26fd3364d81bb744578f95512a4c2c7863 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Tue, 20 Apr 2021 17:03:15 -0400 Subject: [PATCH 4/5] iso-image: Provide the right rEFInd binary --- nixos/modules/installer/cd-dvd/iso-image.nix | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index b876e83e237..7dd3bf23933 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/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}" @@ -362,11 +364,13 @@ let } } + ${lib.optionalString (refindBinary != null) '' menuentry 'rEFInd' --class refind { # UUID is hard-coded in the derivation. search --set=root --no-floppy --fs-uuid 1234-5678 - chainloader (\$root)/EFI/boot/refind_x64.efi + chainloader (\$root)/EFI/boot/${refindBinary} } + ''} menuentry 'Firmware Setup' --class settings { fwsetup clear From cb5c4fcd3c5d4070f040d591b2dd1da580f234d1 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Tue, 20 Apr 2021 17:11:21 -0400 Subject: [PATCH 5/5] iso-image: Hide rEFInd from menu in known non-working situations Looks like GRUB has issues loading EFI binaries from (cd0), which is what would be used in e.g. qemu with OVMF with `-cdrom`. Apparently also what is used with AArch64 + U-Boot USB. --- nixos/modules/installer/cd-dvd/iso-image.nix | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix index 7dd3bf23933..7a4738599b0 100644 --- a/nixos/modules/installer/cd-dvd/iso-image.nix +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -365,11 +365,13 @@ let } ${lib.optionalString (refindBinary != null) '' - menuentry 'rEFInd' --class refind { - # UUID is hard-coded in the derivation. - search --set=root --no-floppy --fs-uuid 1234-5678 - chainloader (\$root)/EFI/boot/${refindBinary} - } + # GRUB apparently cannot do "chainloader" operations on "CD". + if [ "\$root" != "cd0" ]; then + menuentry 'rEFInd' --class refind { + # \$root defaults to the drive the EFI is found on. + chainloader (\$root)/EFI/boot/${refindBinary} + } + fi ''} menuentry 'Firmware Setup' --class settings { fwsetup