about summary refs log tree commit diff
path: root/nixpkgs/pkgs/tools/misc/grub
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/tools/misc/grub')
-rw-r--r--nixpkgs/pkgs/tools/misc/grub/add-hidden-menu-entries.patch204
-rw-r--r--nixpkgs/pkgs/tools/misc/grub/default.nix222
-rw-r--r--nixpkgs/pkgs/tools/misc/grub/fix-bash-completion.patch24
-rw-r--r--nixpkgs/pkgs/tools/misc/grub/pvgrub_image/configs/grub-bootstrap.cfg1
-rw-r--r--nixpkgs/pkgs/tools/misc/grub/pvgrub_image/configs/grub.cfg10
-rw-r--r--nixpkgs/pkgs/tools/misc/grub/pvgrub_image/default.nix44
6 files changed, 505 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/tools/misc/grub/add-hidden-menu-entries.patch b/nixpkgs/pkgs/tools/misc/grub/add-hidden-menu-entries.patch
new file mode 100644
index 000000000000..836a9853708f
--- /dev/null
+++ b/nixpkgs/pkgs/tools/misc/grub/add-hidden-menu-entries.patch
@@ -0,0 +1,204 @@
+diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
+index e9e9d94ef..54e08a1b4 100644
+--- a/grub-core/commands/legacycfg.c
++++ b/grub-core/commands/legacycfg.c
+@@ -143,7 +143,7 @@ legacy_file (const char *filename)
+ 	    args[0] = oldname;
+ 	    grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy",
+ 					NULL, NULL,
+-					entrysrc, 0);
++					entrysrc, 0, 0);
+ 	    grub_free (args);
+ 	    entrysrc[0] = 0;
+ 	    grub_free (oldname);
+@@ -205,7 +205,7 @@ legacy_file (const char *filename)
+ 	}
+       args[0] = entryname;
+       grub_normal_add_menu_entry (1, args, NULL, NULL, NULL,
+-				  NULL, NULL, entrysrc, 0);
++				  NULL, NULL, entrysrc, 0, 0);
+       grub_free (args);
+     }
+ 
+diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c
+index 720e6d8ea..50632ccce 100644
+--- a/grub-core/commands/menuentry.c
++++ b/grub-core/commands/menuentry.c
+@@ -78,7 +78,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
+ 			    char **classes, const char *id,
+ 			    const char *users, const char *hotkey,
+ 			    const char *prefix, const char *sourcecode,
+-			    int submenu)
++			    int submenu, int hidden)
+ {
+   int menu_hotkey = 0;
+   char **menu_args = NULL;
+@@ -188,8 +188,11 @@ grub_normal_add_menu_entry (int argc, const char **args,
+   (*last)->args = menu_args;
+   (*last)->sourcecode = menu_sourcecode;
+   (*last)->submenu = submenu;
++  (*last)->hidden = hidden;
++
++  if (!hidden)
++    menu->size++;
+ 
+-  menu->size++;
+   return GRUB_ERR_NONE;
+ 
+  fail:
+@@ -286,7 +289,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
+ 				       users,
+ 				       ctxt->state[2].arg, 0,
+ 				       ctxt->state[3].arg,
+-				       ctxt->extcmd->cmd->name[0] == 's');
++				       ctxt->extcmd->cmd->name[0] == 's',
++               ctxt->extcmd->cmd->name[0] == 'h');
+ 
+   src = args[argc - 1];
+   args[argc - 1] = NULL;
+@@ -303,7 +307,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
+ 				  ctxt->state[0].args, ctxt->state[4].arg,
+ 				  users,
+ 				  ctxt->state[2].arg, prefix, src + 1,
+-				  ctxt->extcmd->cmd->name[0] == 's');
++				  ctxt->extcmd->cmd->name[0] == 's',
++          ctxt->extcmd->cmd->name[0] == 'h');
+ 
+   src[len - 1] = ch;
+   args[argc - 1] = src;
+@@ -311,7 +316,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
+   return r;
+ }
+ 
+-static grub_extcmd_t cmd, cmd_sub;
++static grub_extcmd_t cmd, cmd_sub, cmd_hidden;
+ 
+ void
+ grub_menu_init (void)
+@@ -327,6 +332,12 @@ grub_menu_init (void)
+ 				  | GRUB_COMMAND_FLAG_EXTRACTOR,
+ 				  N_("BLOCK"), N_("Define a submenu."),
+ 				  options);
++  cmd_hidden = grub_register_extcmd ("hiddenentry", grub_cmd_menuentry,
++                  GRUB_COMMAND_FLAG_BLOCKS
++                  | GRUB_COMMAND_ACCEPT_DASH
++                  | GRUB_COMMAND_FLAG_EXTRACTOR,
++                  N_("BLOCK"), N_("Define a hidden menu entry."),
++                  options);
+ }
+ 
+ void
+diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
+index 6a90e091f..4236f55bc 100644
+--- a/grub-core/normal/menu.c
++++ b/grub-core/normal/menu.c
+@@ -37,6 +37,8 @@
+    entry failing to boot.  */
+ #define DEFAULT_ENTRY_ERROR_DELAY_MS  2500
+ 
++#define MENU_INCLUDE_HIDDEN 0x10000
++
+ grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
+ 				     int nested) = NULL;
+ 
+@@ -80,8 +82,20 @@ grub_menu_get_entry (grub_menu_t menu, int no)
+ {
+   grub_menu_entry_t e;
+ 
+-  for (e = menu->entry_list; e && no > 0; e = e->next, no--)
+-    ;
++  if (no & MENU_INCLUDE_HIDDEN) {
++    no &= ~MENU_INCLUDE_HIDDEN;
++
++    for (e = menu->entry_list; e && no > 0; e = e->next, no--)
++      ;
++  } else {
++    for (e = menu->entry_list; e && no > 0; e = e->next, no--) {
++      /* Skip hidden entries */
++      while (e && e->hidden)
++        e = e->next;
++    }
++    while (e && e->hidden)
++      e = e->next;
++  }
+ 
+   return e;
+ }
+@@ -93,10 +107,10 @@ get_entry_index_by_hotkey (grub_menu_t menu, int hotkey)
+   grub_menu_entry_t entry;
+   int i;
+ 
+-  for (i = 0, entry = menu->entry_list; i < menu->size;
++  for (i = 0, entry = menu->entry_list; entry;
+        i++, entry = entry->next)
+     if (entry->hotkey == hotkey)
+-      return i;
++      return i | MENU_INCLUDE_HIDDEN;
+ 
+   return -1;
+ }
+@@ -509,6 +523,10 @@ get_entry_number (grub_menu_t menu, const char *name)
+       grub_menu_entry_t e = menu->entry_list;
+       int i;
+ 
++       /* Skip hidden entries */
++      while (e && e->hidden)
++        e = e->next;
++
+       grub_errno = GRUB_ERR_NONE;
+ 
+       for (i = 0; e; i++)
+@@ -520,6 +538,10 @@ get_entry_number (grub_menu_t menu, const char *name)
+ 	      break;
+ 	    }
+ 	  e = e->next;
++
++    /* Skip hidden entries */
++    while (e && e->hidden)
++      e = e->next;
+ 	}
+ 
+       if (! e)
+diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
+index b1321eb26..d2e46cac8 100644
+--- a/grub-core/normal/menu_text.c
++++ b/grub-core/normal/menu_text.c
+@@ -289,7 +289,11 @@ print_entries (grub_menu_t menu, const struct menu_viewer_data *data)
+       print_entry (data->geo.first_entry_y + i, data->offset == i,
+ 		   e, data);
+       if (e)
+-	e = e->next;
++	      e = e->next;
++
++      /* Skip hidden entries */
++      while (e && e->hidden)
++        e = e->next;
+     }
+ 
+   grub_term_gotoxy (data->term,
+diff --git a/include/grub/menu.h b/include/grub/menu.h
+index ee2b5e910..eb8a86ba9 100644
+--- a/include/grub/menu.h
++++ b/include/grub/menu.h
+@@ -58,6 +58,8 @@ struct grub_menu_entry
+ 
+   int submenu;
+ 
++  int hidden;
++
+   /* The next element.  */
+   struct grub_menu_entry *next;
+ };
+diff --git a/include/grub/normal.h b/include/grub/normal.h
+index 218cbabcc..bcb412466 100644
+--- a/include/grub/normal.h
++++ b/include/grub/normal.h
+@@ -145,7 +145,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
+ 			    const char *id,
+ 			    const char *users, const char *hotkey,
+ 			    const char *prefix, const char *sourcecode,
+-			    int submenu);
++			    int submenu, int hidden);
+ 
+ grub_err_t
+ grub_normal_set_password (const char *user, const char *password);
diff --git a/nixpkgs/pkgs/tools/misc/grub/default.nix b/nixpkgs/pkgs/tools/misc/grub/default.nix
new file mode 100644
index 000000000000..5fc189a4de11
--- /dev/null
+++ b/nixpkgs/pkgs/tools/misc/grub/default.nix
@@ -0,0 +1,222 @@
+{ lib, stdenv, runCommand, fetchFromSavannah, fetchpatch, flex, bison, python3, autoconf, automake, libtool, bash
+, rsync, gettext, ncurses, libusb-compat-0_1, freetype, qemu, lvm2, unifont, pkg-config
+, buildPackages
+, nixosTests
+, fuse # only needed for grub-mount
+, runtimeShell
+, zfs ? null
+, efiSupport ? false
+, zfsSupport ? false
+, xenSupport ? false
+, kbdcompSupport ? false, ckbcomp
+}:
+
+let
+  pcSystems = {
+    i686-linux.target = "i386";
+    x86_64-linux.target = "i386";
+  };
+
+  efiSystemsBuild = {
+    i686-linux.target = "i386";
+    x86_64-linux.target = "x86_64";
+    armv7l-linux.target = "arm";
+    aarch64-linux.target = "aarch64";
+    riscv32-linux.target = "riscv32";
+    riscv64-linux.target = "riscv64";
+  };
+
+  # For aarch64, we need to use '--target=aarch64-efi' when building,
+  # but '--target=arm64-efi' when installing. Insanity!
+  efiSystemsInstall = {
+    i686-linux.target = "i386";
+    x86_64-linux.target = "x86_64";
+    armv7l-linux.target = "arm";
+    aarch64-linux.target = "arm64";
+    riscv32-linux.target = "riscv32";
+    riscv64-linux.target = "riscv64";
+  };
+
+  canEfi = lib.any (system: stdenv.hostPlatform.system == system) (lib.mapAttrsToList (name: _: name) efiSystemsBuild);
+  inPCSystems = lib.any (system: stdenv.hostPlatform.system == system) (lib.mapAttrsToList (name: _: name) pcSystems);
+
+  gnulib = fetchFromSavannah {
+    repo = "gnulib";
+    # NOTE: keep in sync with bootstrap.conf!
+    rev = "9f48fb992a3d7e96610c4ce8be969cff2d61a01b";
+    hash = "sha256-mzbF66SNqcSlI+xmjpKpNMwzi13yEWoc1Fl7p4snTto=";
+  };
+
+  src = fetchFromSavannah {
+    repo = "grub";
+    rev = "grub-2.12-rc1";
+    hash = "sha256-DrNFzi2o7ZUfL3bMdG63xivZIjcTgv8RODJz7hLJ3WY=";
+  };
+
+  # HACK: the translations are stored on a different server,
+  # not versioned and not included in the git repo, so fetch them
+  # and hope they don't change often
+  locales = runCommand "grub-locales" {
+    nativeBuildInputs = [rsync];
+
+    outputHashAlgo = "sha256";
+    outputHashMode = "recursive";
+    outputHash = "sha256-bQPQ65gAcuUQ8ELB2hKywuXZ0kdC2bBCsUII/b4FkvQ=";
+  }
+  ''
+    mkdir -p po
+    ${src}/linguas.sh
+
+    mv po $out
+  '';
+in (
+
+assert efiSupport -> canEfi;
+assert zfsSupport -> zfs != null;
+assert !(efiSupport && xenSupport);
+
+stdenv.mkDerivation rec {
+  pname = "grub";
+  version = "2.12-rc1";
+  inherit src;
+
+  patches = [
+    ./fix-bash-completion.patch
+    ./add-hidden-menu-entries.patch
+
+    # Revert upstream commit that breaks reading XFS filesystems
+    # FIXME: remove when fixed upstream
+    (fetchpatch {
+      url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=ef7850c757fb3dd2462a512cfa0ff19c89fcc0b1";
+      revert = true;
+      hash = "sha256-p8Kcv9d7ri4eJU6Fgqyzdj0hV5MHSe50AF02FPDJx2Y=";
+    })
+  ];
+
+  postPatch = if kbdcompSupport then ''
+    sed -i util/grub-kbdcomp.in -e 's@\bckbcomp\b@${ckbcomp}/bin/ckbcomp@'
+  '' else ''
+    echo '#! ${runtimeShell}' > util/grub-kbdcomp.in
+    echo 'echo "Compile grub2 with { kbdcompSupport = true; } to enable support for this command."' >> util/grub-kbdcomp.in
+  '';
+
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
+  nativeBuildInputs = [ bison flex python3 pkg-config gettext freetype autoconf automake ];
+  buildInputs = [ ncurses libusb-compat-0_1 freetype lvm2 fuse libtool bash ]
+    ++ lib.optional doCheck qemu
+    ++ lib.optional zfsSupport zfs;
+
+  strictDeps = true;
+
+  hardeningDisable = [ "all" ];
+
+  separateDebugInfo = !xenSupport;
+
+  preConfigure =
+    '' for i in "tests/util/"*.in
+       do
+         sed -i "$i" -e's|/bin/bash|${stdenv.shell}|g'
+       done
+
+       # Apparently, the QEMU executable is no longer called
+       # `qemu-system-i386', even on i386.
+       #
+       # In addition, use `-nodefaults' to avoid errors like:
+       #
+       #  chardev: opening backend "stdio" failed
+       #  qemu: could not open serial device 'stdio': Invalid argument
+       #
+       # See <http://www.mail-archive.com/qemu-devel@nongnu.org/msg22775.html>.
+       sed -i "tests/util/grub-shell.in" \
+           -e's/qemu-system-i386/qemu-system-x86_64 -nodefaults/g'
+
+      unset CPP # setting CPP intereferes with dependency calculation
+
+      patchShebangs .
+
+      GNULIB_REVISION=$(. bootstrap.conf; echo $GNULIB_REVISION)
+      if [ "$GNULIB_REVISION" != ${gnulib.rev} ]; then
+        echo "This version of GRUB requires a different gnulib revision!"
+        echo "We have: ${gnulib.rev}"
+        echo "GRUB needs: $GNULIB_REVISION"
+        exit 1
+      fi
+
+      cp -f --no-preserve=mode ${locales}/* po
+
+      ./bootstrap --no-git --gnulib-srcdir=${gnulib}
+
+      substituteInPlace ./configure --replace '/usr/share/fonts/unifont' '${unifont}/share/fonts'
+    '';
+
+  postConfigure = ''
+    # make sure .po files are up to date to workaround
+    # parallel `msgmerge --update` on autogenerated .po files:
+    #   https://github.com/NixOS/nixpkgs/pull/248747#issuecomment-1676301670
+    make dist
+  '';
+
+  configureFlags = [
+    "--enable-grub-mount" # dep of os-prober
+  ] ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
+    # grub doesn't do cross-compilation as usual and tries to use unprefixed
+    # tools to target the host. Provide toolchain information explicitly for
+    # cross builds.
+    #
+    # Ref: # https://github.com/buildroot/buildroot/blob/master/boot/grub2/grub2.mk#L108
+    "TARGET_CC=${stdenv.cc.targetPrefix}cc"
+    "TARGET_NM=${stdenv.cc.targetPrefix}nm"
+    "TARGET_OBJCOPY=${stdenv.cc.targetPrefix}objcopy"
+    "TARGET_RANLIB=${stdenv.cc.targetPrefix}ranlib"
+    "TARGET_STRIP=${stdenv.cc.targetPrefix}strip"
+  ] ++ lib.optional zfsSupport "--enable-libzfs"
+    ++ lib.optionals efiSupport [ "--with-platform=efi" "--target=${efiSystemsBuild.${stdenv.hostPlatform.system}.target}" "--program-prefix=" ]
+    ++ lib.optionals xenSupport [ "--with-platform=xen" "--target=${efiSystemsBuild.${stdenv.hostPlatform.system}.target}"];
+
+  # save target that grub is compiled for
+  grubTarget = if efiSupport
+               then "${efiSystemsInstall.${stdenv.hostPlatform.system}.target}-efi"
+               else lib.optionalString inPCSystems "${pcSystems.${stdenv.hostPlatform.system}.target}-pc";
+
+  doCheck = false;
+  enableParallelBuilding = true;
+
+  postInstall = ''
+    # Avoid a runtime reference to gcc
+    sed -i $out/lib/grub/*/modinfo.sh -e "/grub_target_cppflags=/ s|'.*'|' '|"
+    # just adding bash to buildInputs wasn't enough to fix the shebang
+    substituteInPlace $out/lib/grub/*/modinfo.sh \
+      --replace ${buildPackages.bash} "/usr/bin/bash"
+  '';
+
+  passthru.tests = {
+    nixos-grub = nixosTests.grub;
+    nixos-install-simple = nixosTests.installer.simple;
+    nixos-install-grub-uefi = nixosTests.installer.simpleUefiGrub;
+    nixos-install-grub-uefi-spec = nixosTests.installer.simpleUefiGrubSpecialisation;
+  };
+
+  meta = with lib; {
+    description = "GNU GRUB, the Grand Unified Boot Loader";
+
+    longDescription =
+      '' GNU GRUB is a Multiboot boot loader. It was derived from GRUB, GRand
+         Unified Bootloader, which was originally designed and implemented by
+         Erich Stefan Boleyn.
+
+         Briefly, the boot loader is the first software program that runs when a
+         computer starts.  It is responsible for loading and transferring
+         control to the operating system kernel software (such as the Hurd or
+         the Linux).  The kernel, in turn, initializes the rest of the
+         operating system (e.g., GNU).
+      '';
+
+    homepage = "https://www.gnu.org/software/grub/";
+
+    license = licenses.gpl3Plus;
+
+    platforms = platforms.gnu ++ platforms.linux;
+
+    maintainers = [ maintainers.samueldr ];
+  };
+})
diff --git a/nixpkgs/pkgs/tools/misc/grub/fix-bash-completion.patch b/nixpkgs/pkgs/tools/misc/grub/fix-bash-completion.patch
new file mode 100644
index 000000000000..97cecdce373f
--- /dev/null
+++ b/nixpkgs/pkgs/tools/misc/grub/fix-bash-completion.patch
@@ -0,0 +1,24 @@
+diff -ubr grub-2.00-orig/util/bash-completion.d/grub-completion.bash.in grub-2.00/util/bash-completion.d/grub-completion.bash.in
+--- grub-2.00-orig/util/bash-completion.d/grub-completion.bash.in	2012-10-16 19:02:36.342733957 +0200
++++ grub-2.00/util/bash-completion.d/grub-completion.bash.in	2012-10-16 19:04:48.262733941 +0200
+@@ -17,6 +17,12 @@
+ # along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ # bash completion for grub
+ 
++have()
++{
++    unset -v have
++    _have $1 && have=yes
++}
++
+ __grub_dir() {
+     local i c=1 boot_dir
+ 
+@@ -479,6 +485,7 @@
+ have ${__grub_script_check_program} && \
+  complete -F _grub_script_check -o filenames ${__grub_script_check_program}
+ 
++unset -f have
+ 
+ # Local variables:
+ # mode: shell-script
diff --git a/nixpkgs/pkgs/tools/misc/grub/pvgrub_image/configs/grub-bootstrap.cfg b/nixpkgs/pkgs/tools/misc/grub/pvgrub_image/configs/grub-bootstrap.cfg
new file mode 100644
index 000000000000..e9883149ab5d
--- /dev/null
+++ b/nixpkgs/pkgs/tools/misc/grub/pvgrub_image/configs/grub-bootstrap.cfg
@@ -0,0 +1 @@
+normal (memdisk)/grub.cfg
diff --git a/nixpkgs/pkgs/tools/misc/grub/pvgrub_image/configs/grub.cfg b/nixpkgs/pkgs/tools/misc/grub/pvgrub_image/configs/grub.cfg
new file mode 100644
index 000000000000..69115b7101c9
--- /dev/null
+++ b/nixpkgs/pkgs/tools/misc/grub/pvgrub_image/configs/grub.cfg
@@ -0,0 +1,10 @@
+# The parentheses around ${root} here to match Grub's config file syntax
+if search -s -f /boot/grub/grub.cfg ; then
+        echo "Reading (${root})/boot/grub/grub.cfg"
+	configfile /boot/grub/grub.cfg
+fi
+
+if search -s -f /grub/grub.cfg ; then
+	echo "Reading (${root})/grub/grub.cfg"
+	configfile /grub/grub.cfg
+fi
diff --git a/nixpkgs/pkgs/tools/misc/grub/pvgrub_image/default.nix b/nixpkgs/pkgs/tools/misc/grub/pvgrub_image/default.nix
new file mode 100644
index 000000000000..b6883e570802
--- /dev/null
+++ b/nixpkgs/pkgs/tools/misc/grub/pvgrub_image/default.nix
@@ -0,0 +1,44 @@
+{ lib, stdenv, grub2_xen }:
+
+let
+  efiSystemsBuild = {
+    i686-linux.target = "i386";
+    x86_64-linux.target = "x86_64";
+    armv7l-linux.target = "arm";
+    aarch64-linux.target = "aarch64";
+    riscv32-linux.target = "riscv32";
+    riscv64-linux.target = "riscv64";
+  };
+
+in (
+
+stdenv.mkDerivation rec {
+  name = "pvgrub-image";
+
+  configs = ./configs;
+
+  buildInputs = [ grub2_xen ];
+
+  buildCommand = ''
+    cp "${configs}"/* .
+    tar -cf memdisk.tar grub.cfg
+    # We include all modules except all_video.mod as otherwise grub will fail printing "no symbol table"
+    # if we include it.
+    grub-mkimage -O "${efiSystemsBuild.${stdenv.hostPlatform.system}.target}-xen" -c grub-bootstrap.cfg \
+      -m memdisk.tar -o "grub-${efiSystemsBuild.${stdenv.hostPlatform.system}.target}-xen.bin" \
+      $(ls "${grub2_xen}/lib/grub/${efiSystemsBuild.${stdenv.hostPlatform.system}.target}-xen/" |grep 'mod''$'|grep -v '^all_video\.mod''$')
+    mkdir -p "$out/lib/grub-xen"
+    cp "grub-${efiSystemsBuild.${stdenv.hostPlatform.system}.target}-xen.bin" $out/lib/grub-xen/
+  '';
+
+  meta = with lib; {
+    description = "PvGrub image for use for booting PV Xen guests";
+
+    longDescription =
+      '' This package provides a PvGrub image for booting Para-Virtualized (PV)
+         Xen guests
+      '';
+
+    platforms = platforms.gnu ++ platforms.linux;
+  };
+})