Difference between revisions of "GRUB/Tips and tricks"

From ArchWiki
Jump to navigation Jump to search
(Merged from GRUB#Tips and tricks)
 
m (→‎Play a tune: add remove flag)
 
(113 intermediate revisions by 47 users not shown)
Line 1: Line 1:
== Tips and tricks ==
+
[[Category:Boot loaders]]
 +
[[es:GRUB (Español)/Tips and tricks]]
 +
[[fr:GRUB/Trucs et Astuces]]
 +
[[ja:GRUB/ヒントとテクニック]]
 +
[[zh-hans:GRUB/Tips and tricks]]
 +
== Alternative installation methods ==
  
=== GUI configuration tools ===
+
=== Install to external USB stick ===
 +
 
 +
==== BIOS ====
 +
Assume your USB stick's first partition is FAT32 and its partition is /dev/sdy1
 +
 
 +
# mkdir -p /mnt/usb
 +
# mount /dev/sdy1 /mnt/usb
 +
# grub-install --target=i386-pc --debug --boot-directory=/mnt/usb/boot /dev/sdy
 +
# grub-mkconfig -o /mnt/usb/boot/grub/grub.cfg
 +
 
 +
Optionally backup configuration files of {{ic|grub.cfg}}:
 +
# mkdir -p /mnt/usb/etc/default
 +
# cp /etc/default/grub /mnt/usb/etc/default
 +
# cp -a /etc/grub.d /mnt/usb/etc
 +
 
 +
# sync; umount /mnt/usb
 +
 
 +
==== EFI ====
 +
 
 +
To have grub write its EFI image to {{ic|''esp''/EFI/BOOT/BOOTX64.efi}}, which the boot firmware will be able to find without any UEFI boot entry, use {{ic|--removable}} when you run {{ic|grub-install}}.
 +
 
 +
=== Install to partition or partitionless disk ===
 +
{{Warning|GRUB '''strongly discourages''' installation to a partition boot sector or a partitionless disk as GRUB Legacy or Syslinux does. This setup is prone to breakage, especially during updates, and is '''not supported''' by the Arch developers.}}
 +
 
 +
To set up grub to a partition boot sector, to a partitionless disk (also called superfloppy) or to a floppy disk, run (using for example {{ic|/dev/sdaX}} as the {{ic|/boot}} partition):
 +
 
 +
# chattr -i /boot/grub/i386-pc/core.img
 +
# grub-install --target=i386-pc --debug --force /dev/sdaX
 +
# chattr +i /boot/grub/i386-pc/core.img
 +
 
 +
{{Note|
 +
* {{ic|/dev/sdaX}} used for example only.
 +
* {{ic|1=--target=i386-pc}} instructs {{ic|grub-install}} to install for BIOS systems only. It is recommended to always use this option to remove ambiguity in ''grub-install''.
 +
}}
 +
 
 +
You need to use the {{ic|--force}} option to allow usage of blocklists and should not use {{ic|1=--grub-setup=/bin/true}} (which is similar to simply generating {{ic|core.img}}).
 +
 
 +
{{ic|grub-install}} will give out warnings like which should give you the idea of what might go wrong with this approach:
 +
 
 +
/sbin/grub-setup: warn: Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea.
 +
/sbin/grub-setup: warn: Embedding is not possible. GRUB can only be installed in this setup by using blocklists.
 +
                        However, blocklists are UNRELIABLE and their use is discouraged.
 +
 
 +
Without {{ic|--force}} you may get the below error and {{ic|grub-setup}} will not setup its boot code in the partition boot sector:
 +
 
 +
/sbin/grub-setup: error: will not proceed with blocklists
 +
 
 +
With {{ic|--force}} you should get:
 +
 
 +
Installation finished. No error reported.
 +
 
 +
The reason why {{ic|grub-setup}} does not by default allow this is because in case of partition or a partitionless disk is that GRUB relies on embedded blocklists in the partition bootsector to locate the {{ic|/boot/grub/i386-pc/core.img}} file and the prefix directory {{ic|/boot/grub}}. The sector locations of {{ic|core.img}} may change whenever the file system in the partition is being altered (files copied, deleted etc.). For more info, see https://bugzilla.redhat.com/show_bug.cgi?id=728742 and https://bugzilla.redhat.com/show_bug.cgi?id=730915.
 +
 
 +
The workaround for this is to set the immutable flag on {{ic|/boot/grub/i386-pc/core.img}} (using {{ic|chattr}} command as mentioned above) so that the sector locations of the {{ic|core.img}} file in the disk is not altered. The immutable flag on {{ic|/boot/grub/i386-pc/core.img}} needs to be set only if GRUB is installed to a partition boot sector or a partitionless disk, not in case of installation to MBR or simple generation of {{ic|core.img}} without embedding any bootsector (mentioned above).
 +
 
 +
Unfortunately, the {{ic|grub.cfg}} file that is created will not contain the proper UUID in order to boot, even if it reports no errors. see https://bbs.archlinux.org/viewtopic.php?pid=1294604#p1294604.
 +
In order to fix this issue the following commands:
 +
 
 +
# mount /dev/sdxY /mnt        #Your root partition.
 +
# mount /dev/sdxZ /mnt/boot  #Your boot partition (if you have one).
 +
# arch-chroot /mnt
 +
# pacman -S linux
 +
# grub-mkconfig -o /boot/grub/grub.cfg
 +
 
 +
=== Generate core.img alone ===
 +
 
 +
To populate the {{ic|/boot/grub}} directory and generate a {{ic|/boot/grub/i386-pc/core.img}} file '''without''' embedding any GRUB bootsector code in the MBR, post-MBR region, or the partition bootsector, add {{ic|1=--grub-setup=/bin/true}} to {{ic|grub-install}}:
 +
 
 +
# grub-install --target=i386-pc --grub-setup=/bin/true --debug /dev/sda
 +
 
 +
{{Note|
 +
* {{ic|/dev/sda}} used for example only.
 +
* {{ic|1=--target=i386-pc}} instructs {{ic|grub-install}} to install for BIOS systems only. It is recommended to always use this option to remove ambiguity in grub-install.
 +
}}
 +
 
 +
You can then chainload GRUB's {{ic|core.img}} from GRUB Legacy or syslinux as a Linux kernel or as a multiboot kernel (see also [[Syslinux#Chainloading]]).
 +
 
 +
== GUI configuration tools ==
  
 
Following package may be installed:
 
Following package may be installed:
* {{App|grub-customizer|Customize the bootloader (GRUB or BURG)|https://launchpad.net/grub-customizer|{{AUR|grub-customizer}}}}
+
* {{App|grub-customizer|GTK customizer for GRUB or BURG|https://launchpad.net/grub-customizer|{{Pkg|grub-customizer}}}}
* {{App|grub2-editor|KDE4 control module for configuring the GRUB bootloader|http://kde-apps.org/content/show.php?content=139643|{{AUR|grub2-editor}}}}
+
* {{App|grub2-editor-frameworks|Unofficial KF5 port of grub2-editor|https://github.com/maz-1/grub2-editor|{{AUR|grub2-editor-frameworks}}}}
* {{App|startupmanager|GUI app for changing the settings of GRUB Legacy, GRUB, Usplash and Splashy ([https://launchpad.net/startup-manager/+announcement/8300 abandonned])|http://sourceforge.net/projects/startup-manager/|{{AUR|startupmanager}}}}
+
* {{App|startupmanager|GUI app for changing the settings of GRUB Legacy, GRUB, Usplash and Splashy ([https://launchpad.net/startup-manager/+announcement/8300 abandoned]) |http://sourceforge.net/projects/startup-manager/|{{AUR|startupmanager}}}}
  
=== Visual configuration ===
+
== Visual configuration ==
In GRUB it is possible, by default, to change the look of the menu. Make sure to initialize, if not done already, GRUB graphical terminal, gfxterm, with proper video mode, gfxmode, in GRUB. This can be seen in the section [[#"No suitable mode found" error]]. This video mode is passed by GRUB to the linux kernel via 'gfxpayload' so any visual configurations need this mode in order to be in effect.
+
In GRUB it is possible, by default, to change the look of the menu. Make sure to initialize, if not done already, GRUB graphical terminal, gfxterm, with proper video mode, gfxmode, in GRUB. This can be seen in the section [[GRUB#"No suitable mode found" error]]. This video mode is passed by GRUB to the linux kernel via 'gfxpayload' so any visual configurations need this mode in order to be in effect.
  
==== Setting the framebuffer resolution ====
+
=== Setting the framebuffer resolution ===
  
GRUB can set the framebuffer for both GRUB itself and the kernel. The old {{ic|1=vga=}} way is deprecated. The preferred method is editing {{ic|/etc/default/grub}} as the following sample:
+
GRUB can set the framebuffer for both GRUB itself and the kernel. The old {{ic|1=vga=}} way is deprecated. The preferred method is editing {{ic|/etc/default/grub}} as the following sample to set width (pixels) x height (pixels) x [[Wikipedia:color depth|color depth]]:
  
 
  GRUB_GFXMODE=1024x768x32
 
  GRUB_GFXMODE=1024x768x32
 
  GRUB_GFXPAYLOAD_LINUX=keep
 
  GRUB_GFXPAYLOAD_LINUX=keep
  
Multiple resolutions can be specified, including the default {{ic|auto}}, so it is recommended that you edit the line to resemble {{ic|1=GRUB_GFXMODE=<desired resolution>,<fallback such as 1024x768>,auto}}. For more information, refer to [https://www.gnu.org/software/grub/manual/html_node/gfxmode.html#gfxmode the GRUB gfxmode documentation]. The [https://www.gnu.org/software/grub/manual/html_node/gfxpayload.html#gfxpayload gfxpayload] property will make sure the kernel keeps the resolution.
+
Multiple resolutions can be specified, including the default {{ic|auto}}, so it is recommended that you edit the line to resemble {{ic|1=GRUB_GFXMODE=<desired resolution>,<fallback such as 1024x768>,auto}}. For more information, refer to [https://www.gnu.org/software/grub/manual/grub/html_node/gfxmode.html the GRUB gfxmode documentation]. The [https://www.gnu.org/software/grub/manual/html_node/gfxpayload.html#gfxpayload gfxpayload] property will make sure the kernel keeps the resolution.
  
{{Note|Only the modes supported by the graphics card via [[wikipedia:VESA BIOS Extensions|VESA BIOS Extensions]] can be used. To view the list of supported modes, install {{Pkg|hwinfo}} and run {{ic|hwinfo --framebuffer}} as root. Alternatively, enter the GRUB command line and run the command {{ic|vbeinfo}}.}}
+
{{Note|
 +
* Only the modes supported by the graphics card via [[wikipedia:VESA BIOS Extensions|VESA BIOS Extensions]] can be used. To view the list of supported modes, install {{Pkg|hwinfo}} and run {{ic|hwinfo --framebuffer}} as root. Alternatively, enter the GRUB command line and run the command {{ic|videoinfo}}.
 +
* Earlier versions of the [[NVIDIA]] proprietary driver (tested with GeForce GTX 970, driver: nvidia 370) accepts {{ic|GRUB_GFXMODE}} in format {{ic|''<width>''x''<height>''-''<depth>''}} (e.g. {{ic|1920x1200-24}}, but not {{ic|1920x1200x24}}). This does not appear to apply to newer cards and drivers. Pascal cards with more recent drivers (tested with GeForce GTX 1060 and nvidia 381.22) will not work with the suggested format and attempting to use it results in serious issues, including but not limited to system crashes and hard locks. The current driver and cards are best configured with {{ic|GRUB_GFXMODE}} in the standard {{ic|''<width>''x''<height>''x''<depth>''}} format.
 +
* Make sure to run {{ic|grub-mkconfig -o /boot/grub/grub.cfg}} after making changes.
 +
}}
  
 
If this method does not work for you, the deprecated {{ic|1=vga=}} method will still work. Just add it next to the {{ic|1="GRUB_CMDLINE_LINUX_DEFAULT="}} line in {{ic|/etc/default/grub}} for example: {{ic|1="GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vga=792"}} will give you a {{ic|1024x768}} resolution.
 
If this method does not work for you, the deprecated {{ic|1=vga=}} method will still work. Just add it next to the {{ic|1="GRUB_CMDLINE_LINUX_DEFAULT="}} line in {{ic|/etc/default/grub}} for example: {{ic|1="GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vga=792"}} will give you a {{ic|1024x768}} resolution.
  
==== 915resolution hack ====
+
=== 915resolution hack ===
Some times for Intel graphic adapters neither {{ic|1=# hwinfo --framebuffer}} nor {{ic|1=vbeinfo}} will show you the desired resolution. In this case you can use {{ic|915resolution}} hack. This hack will temporarily modify video BIOS and add needed resolution. See [http://915resolution.mango-lang.org/ 915resolution's home page]
+
Sometimes for Intel graphic adapters neither {{ic|1=# hwinfo --framebuffer}} nor {{ic|1=videoinfo}} will show you the desired resolution. In this case you can use the {{ic|915resolution}} hack. This hack will temporarily modify video BIOS and add needed resolution. See [http://915resolution.mango-lang.org/ 915resolution's home page]. The package can be found here: {{AUR|915resolution}}
  
 
First you need to find a video mode which will be modified later. For that we need the GRUB command shell:
 
First you need to find a video mode which will be modified later. For that we need the GRUB command shell:
Line 43: Line 129:
 
Lastly we need to set {{ic|GRUB_GFXMODE}} as described earlier, regenerate {{ic|grub.cfg}} and reboot to test changes.
 
Lastly we need to set {{ic|GRUB_GFXMODE}} as described earlier, regenerate {{ic|grub.cfg}} and reboot to test changes.
  
==== Background image and bitmap fonts ====
+
=== Background image and bitmap fonts ===
 
GRUB comes with support for background images and bitmap fonts in {{ic|pf2}} format. The unifont font is included in the {{Pkg|grub}} package under the filename {{ic|unicode.pf2}}, or, as only ASCII characters under the name {{ic|ascii.pf2}}.
 
GRUB comes with support for background images and bitmap fonts in {{ic|pf2}} format. The unifont font is included in the {{Pkg|grub}} package under the filename {{ic|unicode.pf2}}, or, as only ASCII characters under the name {{ic|ascii.pf2}}.
  
Line 55: Line 141:
 
  GRUB_FONT="/path/to/font.pf2"
 
  GRUB_FONT="/path/to/font.pf2"
  
{{Note|If you have installed GRUB on a separate partition, {{ic|/boot/grub/myimage}} becomes {{ic|/grub/myimage}}.}}
+
{{Note|If you have installed GRUB on a separate partition, {{ic|/boot/grub/myimage}} automatically becomes {{ic|/grub/myimage}} in {{ic|grub.cfg}}.}}
  
[[#Generating main configuration file|Re-generate]] {{ic|grub.cfg}} to apply the changes. If adding the splash image was successful, the user will see {{ic|"Found background image..."}} in the terminal as the command is executed. If this phrase is not seen, the image information was probably not incorporated into the {{ic|grub.cfg}} file.
+
[[GRUB#Generate the main configuration file|Re-generate]] {{ic|grub.cfg}} to apply the changes. If adding the splash image was successful, the user will see {{ic|"Found background image..."}} in the terminal as the command is executed. If this phrase is not seen, the image information was probably not incorporated into the {{ic|grub.cfg}} file.
 
   
 
   
 
If the image is not displayed, check:
 
If the image is not displayed, check:
Line 65: Line 151:
 
* The console mode is not enabled in {{ic|/etc/default/grub}}
 
* The console mode is not enabled in {{ic|/etc/default/grub}}
 
* The command {{ic|grub-mkconfig}} must be executed to place the background image information into the {{ic|/boot/grub/grub.cfg}} file
 
* The command {{ic|grub-mkconfig}} must be executed to place the background image information into the {{ic|/boot/grub/grub.cfg}} file
 +
* The {{ic|grub-mkconfig}} scripts won't quote the file name in {{ic|grub.cfg}} so make sure it does not contain spaces
  
==== Theme ====
+
=== Theme ===
 
Here is an example for configuring Starfield theme which was included in GRUB package.
 
Here is an example for configuring Starfield theme which was included in GRUB package.
  
Line 72: Line 159:
 
  GRUB_THEME="/usr/share/grub/themes/starfield/theme.txt"
 
  GRUB_THEME="/usr/share/grub/themes/starfield/theme.txt"
  
[[#Generating main configuration file|Re-generate]] {{ic|grub.cfg}} to apply the changes. If configuring the theme was successful, you will see {{ic|Found theme: /usr/share/grub/themes/starfield/theme.txt}} in the terminal.
+
[[GRUB#Generate the main configuration file|Re-generate]] {{ic|grub.cfg}} to apply the changes. If configuring the theme was successful, you will see {{ic|Found theme: /usr/share/grub/themes/starfield/theme.txt}} in the terminal.
  
 
Your splash image will usually not be displayed when using a theme.
 
Your splash image will usually not be displayed when using a theme.
  
==== Menu colors ====
+
=== Menu colors ===
 
You can set the menu colors in GRUB. The available colors for GRUB can be found in [https://www.gnu.org/software/grub/manual/html_node/Theme-file-format.html the GRUB Manual].
 
You can set the menu colors in GRUB. The available colors for GRUB can be found in [https://www.gnu.org/software/grub/manual/html_node/Theme-file-format.html the GRUB Manual].
 
Here is an example:
 
Here is an example:
Line 84: Line 171:
 
  GRUB_COLOR_HIGHLIGHT="light-cyan/blue"
 
  GRUB_COLOR_HIGHLIGHT="light-cyan/blue"
  
==== Hidden menu ====
+
=== Hidden menu ===
 
One of the unique features of GRUB is hiding/skipping the menu and showing it by holding {{ic|Esc}} when needed. You can also adjust whether you want to see the timeout counter.
 
One of the unique features of GRUB is hiding/skipping the menu and showing it by holding {{ic|Esc}} when needed. You can also adjust whether you want to see the timeout counter.
  
Edit {{ic|/etc/default/grub}} as you wish. Here is an example where the comments from the beginning of the two lines have been removed to enable the feature, the timeout has been set to five seconds and to be shown to the user:
+
Edit {{ic|/etc/default/grub}} as you wish. Here are the lines you need to add to enable this feature, the timeout has been set to five seconds and to be shown to the user:
  GRUB_TIMEOUT=0
+
  GRUB_TIMEOUT=5
GRUB_HIDDEN_TIMEOUT=5
+
  GRUB_TIMEOUT_STYLE='countdown'
  GRUB_HIDDEN_TIMEOUT_QUIET=false
+
GRUB_TIMEOUT is how many seconds before displaying menu.
GRUB_HIDDEN_TIMEOUT is how many seconds before displaying menu. You also need to set GRUB_TIMEOUT=0 if you want to hide menu.
 
  
==== Disable framebuffer ====
+
=== Disable framebuffer ===
 
Users who use NVIDIA proprietary driver might wish to disable GRUB's framebuffer as it can cause problems with the binary driver.
 
Users who use NVIDIA proprietary driver might wish to disable GRUB's framebuffer as it can cause problems with the binary driver.
  
Line 102: Line 188:
 
  GRUB_GFXPAYLOAD_LINUX=text
 
  GRUB_GFXPAYLOAD_LINUX=text
  
=== Booting ISO9660 image file directly via GRUB ===
+
== Booting ISO9660 image file directly via GRUB ==
  
 
GRUB supports booting from ISO images directly via loopback devices, see [[Multiboot USB drive#Using GRUB and loopback devices]] for examples.
 
GRUB supports booting from ISO images directly via loopback devices, see [[Multiboot USB drive#Using GRUB and loopback devices]] for examples.
  
=== Persistent block device naming ===
+
== Persistent block device naming ==
  
 
One naming scheme for [[Persistent block device naming]] is the use of globally unique UUIDs to detect partitions instead of the "old" {{ic|/dev/sd*}}. Advantages are covered up in the above linked article.  
 
One naming scheme for [[Persistent block device naming]] is the use of globally unique UUIDs to detect partitions instead of the "old" {{ic|/dev/sd*}}. Advantages are covered up in the above linked article.  
Line 118: Line 204:
 
  GRUB_DISABLE_LINUX_UUID=true
 
  GRUB_DISABLE_LINUX_UUID=true
  
=== Using labels ===
+
== Using labels ==
 
It is possible to use labels, human-readable strings attached to file systems, by using the {{ic|--label}} option to {{ic|search}}. First of all, label your existing partition:
 
It is possible to use labels, human-readable strings attached to file systems, by using the {{ic|--label}} option to {{ic|search}}. First of all, label your existing partition:
 
  # tune2fs -L ''LABEL'' ''PARTITION''
 
  # tune2fs -L ''LABEL'' ''PARTITION''
Line 130: Line 216:
 
  }
 
  }
  
=== Password protection of GRUB menu ===
+
== Password protection of GRUB menu ==
 +
 
 +
{{Warning|If someone has physical access to your machine and is able to boot a live USB/disk (''i.e.'', BIOS allows booting from an external disk), it's fairly trivial for one to modify GRUB configuration files to bypass this if {{ic|/boot}} resides on an unencrypted partition. See [[GRUB#Encrypted /boot]] and [[Security#Disk encryption]].}}
 +
 
 
If you want to secure GRUB so it is not possible for anyone to change boot parameters or use the command line, you can add a user/password combination to GRUB's configuration files. To do this, run the command {{ic|grub-mkpasswd-pbkdf2}}. Enter a password and confirm it:
 
If you want to secure GRUB so it is not possible for anyone to change boot parameters or use the command line, you can add a user/password combination to GRUB's configuration files. To do this, run the command {{ic|grub-mkpasswd-pbkdf2}}. Enter a password and confirm it:
  
Line 138: Line 227:
 
}}
 
}}
  
Then, add the following to {{ic|/etc/grub.d/40_custom}}:
+
Then, adjust permissions of {{ic|/etc/grub.d/40_custom}} such that only root can read it and add the following to this file:
  
 
{{hc|/etc/grub.d/40_custom|2=
 
{{hc|/etc/grub.d/40_custom|2=
Line 151: Line 240:
 
This can be relaxed and further customized with more users as described in the "Security" part of [https://www.gnu.org/software/grub/manual/grub.html#Security the GRUB manual].
 
This can be relaxed and further customized with more users as described in the "Security" part of [https://www.gnu.org/software/grub/manual/grub.html#Security the GRUB manual].
  
=== Hide GRUB unless the Shift key is held down ===
+
=== Password protection of GRUB edit and console options only ===
In order to achieve the fastest possible boot, instead of having GRUB wait for a timeout, it is possible for GRUB to hide the menu, unless the {{ic|Shift}} key is held down during GRUB's start-up.
 
  
In order to achieve this, you should add the following line to {{ic|/etc/default/grub}}:
+
Adding {{ic|--unrestricted}} to a menu entry will allow any user to boot the OS while preventing the user from editing the entry and preventing access to the grub command console.
 +
Only a superuser or users specified with the {{ic|--user}} switch will be able to edit the menu entry.
  
  GRUB_FORCE_HIDDEN_MENU="true"
+
{{hc|/boot/grub/grub.cfg|2=
 +
menuentry 'Arch Linux' --unrestricted --class arch --class gnu-linux --class os ...
 +
}}
  
And the following file should be created and made executable:
+
{{Accuracy|{{ic|/etc/grub.d/10_linux}} should not be edited, it will be overwritten when {{pkg|grub}} is updated.}}
  
{{hc|/etc/grub.d/31_hold_shift|<nowiki>
+
In order to make Linux entries {{ic|--unrestricted}}, the {{ic|CLASS}} variable in the beginning of {{ic|/etc/grub.d/10_linux}} can be modified.
#! /bin/sh
 
set -e
 
  
prefix="/usr"
+
{{hc|/etc/grub.d/10_linux|2=
exec_prefix="${prefix}"
+
CLASS="--class gnu-linux --class gnu --class os --unrestricted"
datarootdir="${prefix}/share"
+
}}
  
export TEXTDOMAIN=grub
+
== Hide GRUB unless the Shift key is held down ==
export TEXTDOMAINDIR="${datarootdir}/locale"
+
In order to achieve the fastest possible boot, instead of having GRUB wait for a timeout, it is possible for GRUB to hide the menu, unless the {{ic|Shift}} key is held down during GRUB's start-up.
source "${datarootdir}/grub/grub-mkconfig_lib"
 
  
found_other_os=
+
In order to achieve this, you should add the following line to {{ic|/etc/default/grub}}:
  
make_timeout () {
+
   GRUB_FORCE_HIDDEN_MENU="true"
 
 
   if [ "x${GRUB_FORCE_HIDDEN_MENU}" = "xtrue" ] ; then
 
    if [ "x${1}" != "x" ] ; then
 
      if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then
 
    verbose=
 
      else
 
    verbose=" --verbose"
 
      fi
 
 
 
      if [ "x${1}" = "x0" ] ; then
 
    cat <<EOF
 
if [ "x\${timeout}" != "x-1" ]; then
 
  if keystatus; then
 
    if keystatus --shift; then
 
      set timeout=-1
 
    else
 
      set timeout=0
 
    fi
 
  else
 
    if sleep$verbose --interruptible 3 ; then
 
      set timeout=0
 
    fi
 
  fi
 
fi
 
EOF
 
      else
 
    cat << EOF
 
if [ "x\${timeout}" != "x-1" ]; then
 
  if sleep$verbose --interruptible ${GRUB_HIDDEN_TIMEOUT} ; then
 
    set timeout=0
 
  fi
 
fi
 
EOF
 
      fi
 
    fi
 
  fi
 
}
 
 
 
adjust_timeout () {
 
  if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
 
    cat <<EOF
 
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
 
EOF
 
    make_timeout "${GRUB_HIDDEN_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_BUTTON}"
 
    echo else
 
    make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}"
 
    echo fi
 
  else
 
    make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}"
 
  fi
 
}
 
  
  adjust_timeout
+
Then create the file in [https://gist.githubusercontent.com/anonymous/8eb2019db2e278ba99be/raw/257f15100fd46aeeb8e33a7629b209d0a14b9975/gistfile1.sh], make it exectuable, and regenerate the grub configuration:
  
    cat <<EOF
+
# chmod a+x /etc/grub.d/31_hold_shift
if [ "x\${timeout}" != "x-1" ]; then
+
# grub-mkconfig -o /boot/grub/grub.cfg
  if keystatus; then
 
    if keystatus --shift; then
 
      set timeout=-1
 
    else
 
      set timeout=0
 
    fi
 
  else
 
    if sleep$verbose --interruptible 3 ; then
 
      set timeout=0
 
    fi
 
  fi
 
fi
 
EOF
 
</nowiki>}}
 
  
Make that file executable and then regenerate your grub config:
+
{{Note|This setup uses keystatus to detect keypress event so it may not work on some machines.}}
  
chmod a+x /etc/grub.d/31_hold_shift
+
== Combining the use of UUIDs and basic scripting ==
grub-mkconfig -o /boot/grub/grub.cfg
 
 
 
=== Combining the use of UUIDs and basic scripting ===
 
 
If you like the idea of using UUIDs to avoid unreliable BIOS mappings or are struggling with GRUB's syntax, here is an example boot menu item that uses UUIDs and a small script to direct GRUB to the proper disk partitions for your system. All you need to do is replace the UUIDs in the sample with the correct UUIDs for your system. The example applies to a system with a boot and root partition. You will obviously need to modify the GRUB configuration if you have additional partitions:
 
If you like the idea of using UUIDs to avoid unreliable BIOS mappings or are struggling with GRUB's syntax, here is an example boot menu item that uses UUIDs and a small script to direct GRUB to the proper disk partitions for your system. All you need to do is replace the UUIDs in the sample with the correct UUIDs for your system. The example applies to a system with a boot and root partition. You will obviously need to modify the GRUB configuration if you have additional partitions:
  
Line 280: Line 300:
 
</nowiki>}}
 
</nowiki>}}
  
=== Manually creating grub.cfg ===
+
== Multiple entries ==
 +
 
 +
=== Disable submenu ===
 +
 
 +
If you have multiple kernels installed, say linux and linux-lts, by default {{ic|grub-mkconfig}} groups them in a submenu. If you do not like this behaviour you can go back to one single menu by adding the following line to {{ic|/etc/default/grub}}:
 +
 
 +
  GRUB_DISABLE_SUBMENU=y
 +
 
 +
=== Recall previous entry ===
 +
 
 +
GRUB can remember the last entry you booted from and use this as the default entry to boot from next time. This is useful if you have multiple kernels (i.e., the current Arch one and the LTS kernel as a fallback option) or operating systems. To do this, edit {{ic|/etc/default/grub}} and change the value of {{ic|GRUB_DEFAULT}}:
 +
 
 +
GRUB_DEFAULT=saved
 +
 
 +
This ensures that GRUB will default to the saved entry. To enable saving the selected entry, add the following line to {{ic|/etc/default/grub}}:
 +
 
 +
GRUB_SAVEDEFAULT=true
 +
 
 +
This will only work if /boot is not a btrfs, because grub cannot write to btrfs.  But it will generate a misleading error message: "sparse file not allowed. Press any key to continue.".
 +
 
 +
{{Note|Manually added menu items, e.g. Windows in {{ic|/etc/grub.d/40_custom}} or {{ic|/boot/grub/custom.cfg}}, will need {{ic|savedefault}} added.}}
 +
 
 +
=== Changing the default menu entry ===
 +
 
 +
To change the default selected entry, edit {{ic|/etc/default/grub}} and change the value of {{ic|GRUB_DEFAULT}}:
 +
 
 +
Using menu titles :
  
{{Warning|Editing this file is '''strongly discouraged.''' The file is generated by the {{ic|grub-mkconfig}} command, and it is best to edit your {{ic|/etc/default/grub}} or one of the scripts in the {{ic|/etc/grub.d}} directory.}}
+
GRUB_DEFAULT='Advanced options for Arch Linux>Arch Linux, with Linux linux'
  
A basic GRUB config file uses the following options:
+
Using numbers :
* {{ic|(hd''X'',''Y'')}} is the partition ''Y'' on disk ''X'', partition numbers starting at 1, disk numbers starting at 0
 
* {{ic|1=set default=''N''}} is the default boot entry that is chosen after timeout for user action
 
* {{ic|1=set timeout=''M''}} is the time ''M'' to wait in seconds for a user selection before default is booted
 
* {{ic|<nowiki>menuentry "title" {entry options}</nowiki>}} is a boot entry titled {{ic|title}}
 
* {{ic|1=set root=(hd''X'',''Y'')}} sets the boot partition, where the kernel and GRUB modules are stored (boot need not be a separate partition, and may simply be a directory under the "root" partition ({{ic|/}})
 
  
An example configuration:
+
  GRUB_DEFAULT="1>2"
  
{{hc|/boot/grub/grub.cfg|<nowiki>
+
Grub identifies entries in generated menu counted from zero. That means 0 for the first entry which is the default value, 1 for the second and so on. Main and submenu entries are separated
# Config file for GRUB - The GNU GRand Unified Bootloader
+
by a {{ic|>}}.
# /boot/grub/grub.cfg
 
  
# DEVICE NAME CONVERSIONS
+
The example above boots the third entry from the main menu 'Advanced options for Arch Linux'.
#
 
Linux           Grub
 
# -------------------------
 
#  /dev/fd0        (fd0)
 
#  /dev/sda        (hd0)
 
#  /dev/sdb2      (hd1,2)
 
#  /dev/sda3      (hd0,3)
 
#
 
  
# Timeout for menu
+
=== Boot non-default entry only once ===
set timeout=5
 
  
# Set default boot entry as Entry 0
+
The command {{ic|grub-reboot}} is very helpful to boot another entry than the default only once. GRUB loads the entry passed in the first command line argument, when the system is rebooted the next time. Most importantly GRUB returns to loading the default entry for all future booting. Changing the configuration file or selecting an entry in the GRUB menu is not necessary.
set default=0
 
  
# (0) Arch Linux
+
{{Note|This requires {{ic|1=GRUB_DEFAULT=saved}} in {{ic|/etc/default/grub}} (and then regenerating {{ic|grub.cfg}}) or, in case of hand-made {{ic|grub.cfg}}, the line {{ic|1=set default="${saved_entry}"}}.}}
menuentry "Arch Linux" {
+
 
  set root=(hd0,1)
+
== Play a tune ==
  linux /vmlinuz-linux root=/dev/sda3 ro
+
 
  initrd /initramfs-linux.img
+
You can play a tune through the PC-speaker while booting (right before the menu appears) by modifying the variable {{ic|GRUB_INIT_TUNE}}. For example, to play Berlioz's extract from Sabbath Night of Symphonie Fantastique (bassoon part) you can add the following:
 +
 
 +
{{ic|GRUB_INIT_TUNE<nowiki>=</nowiki>"312 262 3 247 3 262 3 220 3 247 3 196 3 220 3 220 3 262 3 262 3 294 3 262 3 247 3 220 3 196 3 247 3 262 3 247 5 220 1 220 5"}}
 +
 
 +
{{Remove|Common samples should be listed elsewhere, there should be just a link.}}
 +
 
 +
You can add a menu entry to play each of these common {{ic|GRUB_INIT_TUNE}} samples by creating the following file and then re-running {{ic|grub-mkconfig}}.
 +
 
 +
{{hc|/etc/grub.d/91_tune_demo|
 +
#!/bin/sh
 +
exec tail -n +3 $0
 +
menuentry "INIT_TUNE Demos" {
 +
  echo "Close Encounters/5 Tone"
 +
  play 480 900 2 1000 2 800 2 400 2 600 3
 +
  echo "Fur Elise (note long)"
 +
  play 480 420 1 400 1 420 1 400 1 420 1 315 1 370 1 335 1 282 3 180 1 215 1 282 1 315 3 213 1 262 1 315 1 335 3 213 1 420 1 400 1 420 1 400 1 420 1 315 1 370 1 335 1 282 3 180 1 215 1 282 1 315 3 213 1 330 1 315 1 282 3
 +
  echo "Berlioz's extract from Sabbath Night of Symphonie Fantastique"
 +
  play 312 262 3 247 3 262 3 220 3 247 3 196 3 220 3 220 3 262 3 262 3 294 3 262 3 247 3 220 3 196 3 247 3 262 3 247 5 220 1 220 5
 +
  echo "Oldskool Batman tune"
 +
  play 380 120 1 140 1 160 1 200 8 190 4
 +
  echo "Legend of Zelda tune"
 +
  play 12000 440 100 0 1 329 150 440 50 0 1 440 25 493 25 523 25 587 25 659 200
 +
  echo "Super Mario"
 +
  play 1000 334 1 334 1 0 1 334 1 0 1 261 1 334 1 0 1 392 2 0 4 196 2
 +
  echo "Super Mario Alternate"
 +
  play 480 165 2 165 2 165 3 554 1 587 1 554 2 370 1 554 1 523 2 349 1 523 1 494 3 165 2 165 2 165 2
 +
  echo "Mario Mushroom"
 +
  play 1750 523 1 392 1 523 1 659 1 784 1 1047 1 784 1 415 1 523 1 622 1 831 1 622 1 831 1 1046 1 1244 1 1661 1 1244 1 466 1 587 1 698 1 932 1 1175 1 1397 1 1865 1 1397 1
 +
  echo "Star Wars Imperial Death March"
 +
  play 480 440 4 440 4 440 4 349 3 523 1 440 4 349 3 523 1 440 8 659 4 659 4 659 4 698 3 523 1 415 4 349 3 523 1 440 8
 +
  echo "My Little Pony"
 +
  play 2400 587 18 554 4 587 8 659 12 587 16 0 10 587 4 659 4 740 8 587 4 784 12 740 8 659 8 587 4 740 20 587 40
 +
  echo "Wolfenstein 3D"
 +
  play 300 131 1 196 1 196 1 196 1 294 1 196 1 294 1 196 1 131 1
 +
  echo "Mall (Nothing Special)"
 +
  play 180 440 1 554 1 659 1
 +
  echo "Final Countdown"
 +
  play 480 554 1 494 1 554 4 370 6 10 3 587 1 554 1 587 2 554 2 494 6
 +
  echo "Xie-Jelei's Tune"
 +
  play 2000 400 4 0 1 500 4 0 1 600 4 0 1 800 6
 +
  echo "Random tune"
 +
  play 480 220 1 277 1 330 1 440 1 185 1 220 1 277 1 370 1 294 1 370 1 440 1 587 1 330 1 415 1 494 1 659 1
 +
  echo "Fleetwood Mac: The Chain Bass Riff (about 5 seconds)"
 +
  play 304 55 5 0 1 55 1 62 1 65 2 62 1 55 1 49 1 55 1 62 2 41 8
 +
  echo "Fleetwood Mac: The Chain Bass Riff Extended Version (WARNING, 25 SECONDS)"
 +
  play 9120 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 120 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 60 41 12 42 3 43 3 44 3 45 3 46 6 47 3 48 3 49 6 50 3 51 3 52 6 53 3 54 3 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 240 82 20 0 10 82 26 0 4 82 26 0 4 82 26 0 4 82 56 0 4 82 60 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 120
 
}
 
}
 +
}}
 +
 +
For information on this, you can look at {{ic|info grub -n play}}.
 +
 +
== Manual configuration of core image for early boot ==
 +
 +
If you require a special keymap or other complex steps that GRUB is not able to configure automatically in order to make {{ic|/boot}} available to the GRUB environment, you can generate a core image yourself. On UEFI systems, the core image is the {{ic|grubx64.efi}} file that is loaded by the firmware on boot. Building your own core image will allow you to embed any modules required for very early boot, as well as a configuration script to bootstrap GRUB.
 +
 +
Firstly, taking as an example a requirement for the {{ic|dvorak}} keymap embedded in early-boot in order to enter a password for a crypted {{ic|/boot}} on a UEFI system:
 +
 +
Determine from the generated {{ic|/boot/grub/grub.cfg}} file what modules are required in order to mount the crypted {{ic|/boot}}. For instance, under your {{ic|menuentry}} you should see lines similar to:
 +
 +
{{bc|1=
 +
insmod diskfilter cryptodisk luks gcry_rijndael gcry_rijndael gcry_sha256
 +
insmod ext2
 +
cryptomount -u 1234abcdef1234abcdef1234abcdef
 +
set root='cryptouuid/1234abcdef1234abcdef1234abcdef'
 +
}}
 +
 +
Take note of all of those modules: they'll need to be included in the core image. Now, create a tarball containing your keymap. This will be bundled in the core image as a memdisk:
 +
 +
# grub-kbdcomp -o dvorak.gkb dvorak
 +
# tar cf memdisk.tar dvorak.gkb
 +
 +
Now create a configuration file to be used in the GRUB core image. This is in the same format as your regular grub config, but need contain only a few lines to find and load the main config file on the {{ic|/boot}} partition:
 +
 +
{{hc|early-grub.cfg|2=
 +
set root=(memdisk)
 +
set prefix=($root)/
 +
 +
terminal_input at_keyboard
 +
keymap /dvorak.gkb
 +
 +
cryptomount -u 1234abcdef1234abcdef1234abcdef
 +
set root='cryptouuid/1234abcdef1234abcdef1234abcdef'
 +
set prefix=($root)/grub
 +
 +
configfile grub.cfg
 +
}}
 +
 +
Finally, generate the core image, listing all of the modules determined to be required in the generated {{ic|grub.cfg}}, along with any modules used in the {{ic|early-grub.cfg}} script. The example above needs {{ic|memdisk}}, {{ic|tar}}, {{ic|at_keyboard}}, {{ic|keylayouts}} and {{ic|configfile}}.
 +
 +
# grub-mkimage -c early-grub.cfg -o grubx64.efi -O x86_64-efi -m memdisk.tar diskfilter cryptodisk luks gcry_rijndael gcry_sha256 ext2 memdisk tar at_keyboard keylayouts configfile
 +
 +
The generated EFI core image can now be used in the same way as the image that is generated automatically by {{ic|grub-install}}: place it in your EFI partition and enable it with {{ic|efibootmgr}}, or configure as appropriate for your system firmware.
 +
 +
== UEFI further reading ==
 +
 +
{{Style|This could be made more concise, better organized.}}
 +
 +
Below is other relevant information regarding installing Arch via UEFI.
 +
 +
=== Alternative install method ===
 +
 +
Usually, GRUB keeps all files, including configuration files, in {{ic|/boot}}, regardless of where the EFI System Partition is mounted.
 +
 +
If you want to keep these files inside the EFI System Partition itself, add {{ic|1=--boot-directory=''esp''}} to the grub-install command:
 +
 +
# grub-install --target=x86_64-efi --efi-directory=''esp'' --bootloader-id=grub --boot-directory=''esp'' --debug
 +
 +
This puts all GRUB files in {{ic|''esp''/grub}}, instead of in {{ic|/boot/grub}}. When using this method, make sure you have ''grub-mkconfig'' put the configuration file in the same place:
 +
 +
# grub-mkconfig -o ''esp''/grub/grub.cfg
 +
 +
Configuration is otherwise the same.
 +
 +
=== UEFI firmware workaround ===
 +
 +
{{Remove|Duplicates [[GRUB#Default/fallback boot path]].}}
 +
 +
Some UEFI firmware requires that the bootable ''.efi'' stub have a specific name and be placed in a specific location: {{ic|''esp''/EFI/boot/bootx64.efi}} (where {{ic|''esp''}} is the UEFI partition mountpoint). Failure to do so in such instances will result in an unbootable installation. Fortunately, this will not cause any problems with other firmware that does not require this.
 +
 +
To do so, first create the necessary directory, and then copy across the grub {{ic|.efi}} stub, renaming it in the process:
 +
 +
# mkdir ''esp''/EFI/boot
 +
# cp ''esp''/EFI/grub_uefi/grubx64.efi ''esp''/EFI/boot/bootx64.efi
 +
 +
=== Create a GRUB entry in the firmware boot manager ===
 +
{{ic|grub-install}} automatically tries to create a menu entry in the boot manager. If it does not, then see [[UEFI#efibootmgr]] for instructions to use {{ic|efibootmgr}} to create a menu entry. However, the problem is likely to be that you have not booted your CD/USB in UEFI mode, as in [[UEFI#Create UEFI bootable USB from ISO]].
 +
 +
=== GRUB standalone ===
 +
 +
This section assumes you are creating a standalone GRUB for x86_64 systems (x86_64-efi). For 32-bit (IA32) EFI systems, replace {{ic|x86_64-efi}} with {{ic|i386-efi}} where appropriate.
 +
 +
It is possible to create a {{ic|grubx64_standalone.efi}} application which has all the modules embedded in a tar archive within the UEFI application, thus removing the need to have a separate directory populated with all of the GRUB UEFI modules and other related files. This is done using the {{ic|grub-mkstandalone}} command (included in {{Pkg|grub}}) as follows:
 +
 +
# echo 'configfile ${cmdpath}/grub.cfg' > /tmp/grub.cfg
 +
# grub-mkstandalone -d /usr/lib/grub/x86_64-efi/ -O x86_64-efi --modules="part_gpt part_msdos" --locales="en@quot" --themes="" -o "''esp''/EFI/grub/grubx64_standalone.efi" "boot/grub/grub.cfg=/tmp/grub.cfg" -v
  
## (1) Windows
+
Then copy the GRUB config file to {{ic|''esp''/EFI/grub/grub.cfg}} and create a UEFI Boot Manager entry for {{ic|''esp''/EFI/grub/grubx64_standalone.efi}} using [[UEFI#efibootmgr|efibootmgr]].
#menuentry "Windows" {
+
 
set root=(hd0,3)
+
{{Note|The option {{ic|1=--modules="part_gpt part_msdos"}} (with the quotes) is necessary for the {{ic|${cmdpath} }} feature to work properly.}}
#  chainloader +1
+
 
#}
+
{{Warning|You may find that the {{ic|grub.cfg}} file is not loaded due to {{ic|${cmdpath} }} missing a slash (i.e. {{ic|(hd1,msdos2)EFI/Boot}} instead of {{ic|(hd1,msdos2)/EFI/Boot}}) and so you are dropped into a GRUB shell. If this happens determine what {{ic|${cmdpath} }} is set to ({{ic|echo ${cmdpath} }}) and then load the config file manually (e.g. {{ic|configfile (hd1,msdos2)/EFI/Boot/grub.cfg}}).}}
</nowiki>}}
+
 
 +
==== Technical information ====
 +
 
 +
The GRUB EFI file always expects its config file to be at {{ic|${prefix}/grub.cfg}}. However in the standalone GRUB EFI file, the {{ic|${prefix} }} is located inside a tar archive and embedded inside the standalone GRUB EFI file itself (inside the GRUB environment, it is denoted by {{ic|"(memdisk)"}}, without quotes). This tar archive contains all the files that would be stored normally at {{ic|/boot/grub}} in case of a normal GRUB EFI install.
 +
 
 +
Due to this embedding of {{ic|/boot/grub}} contents inside the standalone image itself, it does not rely on actual (external) {{ic|/boot/grub}} for anything. Thus in case of standalone GRUB EFI file {{ic|1=${prefix}==(memdisk)/boot/grub}} and the standalone GRUB EFI file reads expects the config file to be at {{ic|1=${prefix}/grub.cfg==(memdisk)/boot/grub/grub.cfg}}.
 +
 
 +
Hence to make sure the standalone GRUB EFI file reads the external {{ic|grub.cfg}} located in the same directory as the EFI file (inside the GRUB environment, it is denoted by {{ic|${cmdpath} }}), we create a simple {{ic|/tmp/grub.cfg}} which instructs GRUB to use {{ic|${cmdpath}/grub.cfg}} as its config ({{ic|configfile ${cmdpath}/grub.cfg}} command in {{ic|(memdisk)/boot/grub/grub.cfg}}). We then instruct grub-mkstandalone to copy this {{ic|/tmp/grub.cfg}} file to {{ic|${prefix}/grub.cfg}} (which is actually {{ic|(memdisk)/boot/grub/grub.cfg}}) using the option {{ic|1="boot/grub/grub.cfg=/tmp/grub.cfg"}}.
 +
 
 +
This way, the standalone GRUB EFI file and actual {{ic|grub.cfg}} can be stored in any directory inside the EFI System Partition (as long as they are in the same directory), thus making them portable.

Latest revision as of 08:18, 5 January 2020

Alternative installation methods

Install to external USB stick

BIOS

Assume your USB stick's first partition is FAT32 and its partition is /dev/sdy1

# mkdir -p /mnt/usb
# mount /dev/sdy1 /mnt/usb
# grub-install --target=i386-pc --debug --boot-directory=/mnt/usb/boot /dev/sdy
# grub-mkconfig -o /mnt/usb/boot/grub/grub.cfg

Optionally backup configuration files of grub.cfg:

# mkdir -p /mnt/usb/etc/default
# cp /etc/default/grub /mnt/usb/etc/default
# cp -a /etc/grub.d /mnt/usb/etc
# sync; umount /mnt/usb

EFI

To have grub write its EFI image to esp/EFI/BOOT/BOOTX64.efi, which the boot firmware will be able to find without any UEFI boot entry, use --removable when you run grub-install.

Install to partition or partitionless disk

Warning: GRUB strongly discourages installation to a partition boot sector or a partitionless disk as GRUB Legacy or Syslinux does. This setup is prone to breakage, especially during updates, and is not supported by the Arch developers.

To set up grub to a partition boot sector, to a partitionless disk (also called superfloppy) or to a floppy disk, run (using for example /dev/sdaX as the /boot partition):

# chattr -i /boot/grub/i386-pc/core.img
# grub-install --target=i386-pc --debug --force /dev/sdaX
# chattr +i /boot/grub/i386-pc/core.img
Note:
  • /dev/sdaX used for example only.
  • --target=i386-pc instructs grub-install to install for BIOS systems only. It is recommended to always use this option to remove ambiguity in grub-install.

You need to use the --force option to allow usage of blocklists and should not use --grub-setup=/bin/true (which is similar to simply generating core.img).

grub-install will give out warnings like which should give you the idea of what might go wrong with this approach:

/sbin/grub-setup: warn: Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea.
/sbin/grub-setup: warn: Embedding is not possible. GRUB can only be installed in this setup by using blocklists.
                        However, blocklists are UNRELIABLE and their use is discouraged.

Without --force you may get the below error and grub-setup will not setup its boot code in the partition boot sector:

/sbin/grub-setup: error: will not proceed with blocklists

With --force you should get:

Installation finished. No error reported.

The reason why grub-setup does not by default allow this is because in case of partition or a partitionless disk is that GRUB relies on embedded blocklists in the partition bootsector to locate the /boot/grub/i386-pc/core.img file and the prefix directory /boot/grub. The sector locations of core.img may change whenever the file system in the partition is being altered (files copied, deleted etc.). For more info, see https://bugzilla.redhat.com/show_bug.cgi?id=728742 and https://bugzilla.redhat.com/show_bug.cgi?id=730915.

The workaround for this is to set the immutable flag on /boot/grub/i386-pc/core.img (using chattr command as mentioned above) so that the sector locations of the core.img file in the disk is not altered. The immutable flag on /boot/grub/i386-pc/core.img needs to be set only if GRUB is installed to a partition boot sector or a partitionless disk, not in case of installation to MBR or simple generation of core.img without embedding any bootsector (mentioned above).

Unfortunately, the grub.cfg file that is created will not contain the proper UUID in order to boot, even if it reports no errors. see https://bbs.archlinux.org/viewtopic.php?pid=1294604#p1294604. In order to fix this issue the following commands:

# mount /dev/sdxY /mnt        #Your root partition.
# mount /dev/sdxZ /mnt/boot   #Your boot partition (if you have one).
# arch-chroot /mnt
# pacman -S linux
# grub-mkconfig -o /boot/grub/grub.cfg

Generate core.img alone

To populate the /boot/grub directory and generate a /boot/grub/i386-pc/core.img file without embedding any GRUB bootsector code in the MBR, post-MBR region, or the partition bootsector, add --grub-setup=/bin/true to grub-install:

# grub-install --target=i386-pc --grub-setup=/bin/true --debug /dev/sda
Note:
  • /dev/sda used for example only.
  • --target=i386-pc instructs grub-install to install for BIOS systems only. It is recommended to always use this option to remove ambiguity in grub-install.

You can then chainload GRUB's core.img from GRUB Legacy or syslinux as a Linux kernel or as a multiboot kernel (see also Syslinux#Chainloading).

GUI configuration tools

Following package may be installed:

  • grub-customizer — GTK customizer for GRUB or BURG
https://launchpad.net/grub-customizer || grub-customizer
  • grub2-editor-frameworks — Unofficial KF5 port of grub2-editor
https://github.com/maz-1/grub2-editor || grub2-editor-frameworksAUR
  • startupmanager — GUI app for changing the settings of GRUB Legacy, GRUB, Usplash and Splashy (abandoned)
http://sourceforge.net/projects/startup-manager/ || startupmanagerAUR

Visual configuration

In GRUB it is possible, by default, to change the look of the menu. Make sure to initialize, if not done already, GRUB graphical terminal, gfxterm, with proper video mode, gfxmode, in GRUB. This can be seen in the section GRUB#"No suitable mode found" error. This video mode is passed by GRUB to the linux kernel via 'gfxpayload' so any visual configurations need this mode in order to be in effect.

Setting the framebuffer resolution

GRUB can set the framebuffer for both GRUB itself and the kernel. The old vga= way is deprecated. The preferred method is editing /etc/default/grub as the following sample to set width (pixels) x height (pixels) x color depth:

GRUB_GFXMODE=1024x768x32
GRUB_GFXPAYLOAD_LINUX=keep

Multiple resolutions can be specified, including the default auto, so it is recommended that you edit the line to resemble GRUB_GFXMODE=<desired resolution>,<fallback such as 1024x768>,auto. For more information, refer to the GRUB gfxmode documentation. The gfxpayload property will make sure the kernel keeps the resolution.

Note:
  • Only the modes supported by the graphics card via VESA BIOS Extensions can be used. To view the list of supported modes, install hwinfo and run hwinfo --framebuffer as root. Alternatively, enter the GRUB command line and run the command videoinfo.
  • Earlier versions of the NVIDIA proprietary driver (tested with GeForce GTX 970, driver: nvidia 370) accepts GRUB_GFXMODE in format <width>x<height>-<depth> (e.g. 1920x1200-24, but not 1920x1200x24). This does not appear to apply to newer cards and drivers. Pascal cards with more recent drivers (tested with GeForce GTX 1060 and nvidia 381.22) will not work with the suggested format and attempting to use it results in serious issues, including but not limited to system crashes and hard locks. The current driver and cards are best configured with GRUB_GFXMODE in the standard <width>x<height>x<depth> format.
  • Make sure to run grub-mkconfig -o /boot/grub/grub.cfg after making changes.

If this method does not work for you, the deprecated vga= method will still work. Just add it next to the "GRUB_CMDLINE_LINUX_DEFAULT=" line in /etc/default/grub for example: "GRUB_CMDLINE_LINUX_DEFAULT="quiet splash vga=792" will give you a 1024x768 resolution.

915resolution hack

Sometimes for Intel graphic adapters neither # hwinfo --framebuffer nor videoinfo will show you the desired resolution. In this case you can use the 915resolution hack. This hack will temporarily modify video BIOS and add needed resolution. See 915resolution's home page. The package can be found here: 915resolutionAUR

First you need to find a video mode which will be modified later. For that we need the GRUB command shell:

sh:grub> 915resolution -l
Intel 800/900 Series VBIOS Hack : version 0.5.3
[...]
Mode 30 : 640x480, 8 bits/pixel
[...]

Next, we overwrite the Mode 30 with 1440x900 resolution:

/etc/grub.d/00_header
[...]
915resolution 30 1440 900  # Inserted line
set gfxmode=${GRUB_GFXMODE}
[...]

Lastly we need to set GRUB_GFXMODE as described earlier, regenerate grub.cfg and reboot to test changes.

Background image and bitmap fonts

GRUB comes with support for background images and bitmap fonts in pf2 format. The unifont font is included in the grub package under the filename unicode.pf2, or, as only ASCII characters under the name ascii.pf2.

Image formats supported include tga, png and jpeg, providing the correct modules are loaded. The maximum supported resolution depends on your hardware.

Make sure you have set up the proper framebuffer resolution.

Edit /etc/default/grub like this:

GRUB_BACKGROUND="/boot/grub/myimage"
#GRUB_THEME="/path/to/gfxtheme"
GRUB_FONT="/path/to/font.pf2"
Note: If you have installed GRUB on a separate partition, /boot/grub/myimage automatically becomes /grub/myimage in grub.cfg.

Re-generate grub.cfg to apply the changes. If adding the splash image was successful, the user will see "Found background image..." in the terminal as the command is executed. If this phrase is not seen, the image information was probably not incorporated into the grub.cfg file.

If the image is not displayed, check:

  • The path and the filename in /etc/default/grub are correct
  • The image is of the proper size and format (tga, png, 8-bit jpg)
  • The image was saved in the RGB mode, and is not indexed
  • The console mode is not enabled in /etc/default/grub
  • The command grub-mkconfig must be executed to place the background image information into the /boot/grub/grub.cfg file
  • The grub-mkconfig scripts won't quote the file name in grub.cfg so make sure it does not contain spaces

Theme

Here is an example for configuring Starfield theme which was included in GRUB package.

Edit /etc/default/grub

GRUB_THEME="/usr/share/grub/themes/starfield/theme.txt"

Re-generate grub.cfg to apply the changes. If configuring the theme was successful, you will see Found theme: /usr/share/grub/themes/starfield/theme.txt in the terminal.

Your splash image will usually not be displayed when using a theme.

Menu colors

You can set the menu colors in GRUB. The available colors for GRUB can be found in the GRUB Manual. Here is an example:

Edit /etc/default/grub:

GRUB_COLOR_NORMAL="light-blue/black"
GRUB_COLOR_HIGHLIGHT="light-cyan/blue"

Hidden menu

One of the unique features of GRUB is hiding/skipping the menu and showing it by holding Esc when needed. You can also adjust whether you want to see the timeout counter.

Edit /etc/default/grub as you wish. Here are the lines you need to add to enable this feature, the timeout has been set to five seconds and to be shown to the user:

GRUB_TIMEOUT=5
GRUB_TIMEOUT_STYLE='countdown'

GRUB_TIMEOUT is how many seconds before displaying menu.

Disable framebuffer

Users who use NVIDIA proprietary driver might wish to disable GRUB's framebuffer as it can cause problems with the binary driver.

To disable framebuffer, edit /etc/default/grub and uncomment the following line:

GRUB_TERMINAL_OUTPUT=console

Another option if you want to keep the framebuffer in GRUB is to revert to text mode just before starting the kernel. To do that modify the variable in /etc/default/grub:

GRUB_GFXPAYLOAD_LINUX=text

Booting ISO9660 image file directly via GRUB

GRUB supports booting from ISO images directly via loopback devices, see Multiboot USB drive#Using GRUB and loopback devices for examples.

Persistent block device naming

One naming scheme for Persistent block device naming is the use of globally unique UUIDs to detect partitions instead of the "old" /dev/sd*. Advantages are covered up in the above linked article.

Persistent naming via file system UUIDs are used by default in GRUB.

Note: The /boot/grub.cfg file needs regeneration with the new UUID in /etc/default/grub every time a relevant file system is resized or recreated. Remember this when modifying partitions & file systems with a Live-CD.

Whether to use UUIDs is controlled by an option in /etc/default/grub:

GRUB_DISABLE_LINUX_UUID=true

Using labels

It is possible to use labels, human-readable strings attached to file systems, by using the --label option to search. First of all, label your existing partition:

# tune2fs -L LABEL PARTITION

Then, add an entry using labels. An example of this:

menuentry "Arch Linux, session texte" {
  search --label --set=root archroot
  linux /boot/vmlinuz-linux root=/dev/disk/by-label/archroot ro
  initrd /boot/initramfs-linux.img
}

Password protection of GRUB menu

Warning: If someone has physical access to your machine and is able to boot a live USB/disk (i.e., BIOS allows booting from an external disk), it's fairly trivial for one to modify GRUB configuration files to bypass this if /boot resides on an unencrypted partition. See GRUB#Encrypted /boot and Security#Disk encryption.

If you want to secure GRUB so it is not possible for anyone to change boot parameters or use the command line, you can add a user/password combination to GRUB's configuration files. To do this, run the command grub-mkpasswd-pbkdf2. Enter a password and confirm it:

grub-mkpasswd-pbkdf2
[...]
Your PBKDF2 is grub.pbkdf2.sha512.10000.C8ABD3E93C4DFC83138B0C7A3D719BC650E6234310DA069E6FDB0DD4156313DA3D0D9BFFC2846C21D5A2DDA515114CF6378F8A064C94198D0618E70D23717E82.509BFA8A4217EAD0B33C87432524C0B6B64B34FBAD22D3E6E6874D9B101996C5F98AB1746FE7C7199147ECF4ABD8661C222EEEDB7D14A843261FFF2C07B1269A

Then, adjust permissions of /etc/grub.d/40_custom such that only root can read it and add the following to this file:

/etc/grub.d/40_custom
set superusers="username"
password_pbkdf2 username <password>

where <password> is the string generated by grub-mkpasswd_pbkdf2.

Regenerate your configuration file. Your GRUB command line, boot parameters and all boot entries are now protected.

This can be relaxed and further customized with more users as described in the "Security" part of the GRUB manual.

Password protection of GRUB edit and console options only

Adding --unrestricted to a menu entry will allow any user to boot the OS while preventing the user from editing the entry and preventing access to the grub command console. Only a superuser or users specified with the --user switch will be able to edit the menu entry.

/boot/grub/grub.cfg
menuentry 'Arch Linux' --unrestricted --class arch --class gnu-linux --class os ...

Tango-inaccurate.pngThe factual accuracy of this article or section is disputed.Tango-inaccurate.png

Reason: /etc/grub.d/10_linux should not be edited, it will be overwritten when grub is updated. (Discuss in Talk:GRUB/Tips and tricks#)

In order to make Linux entries --unrestricted, the CLASS variable in the beginning of /etc/grub.d/10_linux can be modified.

/etc/grub.d/10_linux
CLASS="--class gnu-linux --class gnu --class os --unrestricted"

Hide GRUB unless the Shift key is held down

In order to achieve the fastest possible boot, instead of having GRUB wait for a timeout, it is possible for GRUB to hide the menu, unless the Shift key is held down during GRUB's start-up.

In order to achieve this, you should add the following line to /etc/default/grub:

 GRUB_FORCE_HIDDEN_MENU="true"

Then create the file in [1], make it exectuable, and regenerate the grub configuration:

# chmod a+x /etc/grub.d/31_hold_shift
# grub-mkconfig -o /boot/grub/grub.cfg
Note: This setup uses keystatus to detect keypress event so it may not work on some machines.

Combining the use of UUIDs and basic scripting

If you like the idea of using UUIDs to avoid unreliable BIOS mappings or are struggling with GRUB's syntax, here is an example boot menu item that uses UUIDs and a small script to direct GRUB to the proper disk partitions for your system. All you need to do is replace the UUIDs in the sample with the correct UUIDs for your system. The example applies to a system with a boot and root partition. You will obviously need to modify the GRUB configuration if you have additional partitions:

menuentry "Arch Linux 64" {
    # Set the UUIDs for your boot and root partition respectively
    set the_boot_uuid=ece0448f-bb08-486d-9864-ac3271bd8d07
    set the_root_uuid=c55da16f-e2af-4603-9e0b-03f5f565ec4a

    # (Note: This may be the same as your boot partition)

    # Get the boot/root devices and set them in the root and grub_boot variables
    search --fs-uuid $the_root_uuid --set=root
    search --fs-uuid $the_boot_uuid --set=grub_boot

    # Check to see if boot and root are equal.
    # If they are, then append /boot to $grub_boot (Since $grub_boot is actually the root partition)
    if [ $the_boot_uuid == $the_root_uuid ] ; then
        set grub_boot=($grub_boot)/boot
    else
        set grub_boot=($grub_boot)
    fi

    # $grub_boot now points to the correct location, so the following will properly find the kernel and initrd
    linux $grub_boot/vmlinuz-linux root=/dev/disk/by-uuid/$the_root_uuid ro
    initrd $grub_boot/initramfs-linux.img
}

Multiple entries

Disable submenu

If you have multiple kernels installed, say linux and linux-lts, by default grub-mkconfig groups them in a submenu. If you do not like this behaviour you can go back to one single menu by adding the following line to /etc/default/grub:

 GRUB_DISABLE_SUBMENU=y

Recall previous entry

GRUB can remember the last entry you booted from and use this as the default entry to boot from next time. This is useful if you have multiple kernels (i.e., the current Arch one and the LTS kernel as a fallback option) or operating systems. To do this, edit /etc/default/grub and change the value of GRUB_DEFAULT:

GRUB_DEFAULT=saved

This ensures that GRUB will default to the saved entry. To enable saving the selected entry, add the following line to /etc/default/grub:

GRUB_SAVEDEFAULT=true

This will only work if /boot is not a btrfs, because grub cannot write to btrfs. But it will generate a misleading error message: "sparse file not allowed. Press any key to continue.".

Note: Manually added menu items, e.g. Windows in /etc/grub.d/40_custom or /boot/grub/custom.cfg, will need savedefault added.

Changing the default menu entry

To change the default selected entry, edit /etc/default/grub and change the value of GRUB_DEFAULT:

Using menu titles :

GRUB_DEFAULT='Advanced options for Arch Linux>Arch Linux, with Linux linux'

Using numbers :

 GRUB_DEFAULT="1>2"

Grub identifies entries in generated menu counted from zero. That means 0 for the first entry which is the default value, 1 for the second and so on. Main and submenu entries are separated by a >.

The example above boots the third entry from the main menu 'Advanced options for Arch Linux'.

Boot non-default entry only once

The command grub-reboot is very helpful to boot another entry than the default only once. GRUB loads the entry passed in the first command line argument, when the system is rebooted the next time. Most importantly GRUB returns to loading the default entry for all future booting. Changing the configuration file or selecting an entry in the GRUB menu is not necessary.

Note: This requires GRUB_DEFAULT=saved in /etc/default/grub (and then regenerating grub.cfg) or, in case of hand-made grub.cfg, the line set default="${saved_entry}".

Play a tune

You can play a tune through the PC-speaker while booting (right before the menu appears) by modifying the variable GRUB_INIT_TUNE. For example, to play Berlioz's extract from Sabbath Night of Symphonie Fantastique (bassoon part) you can add the following:

GRUB_INIT_TUNE="312 262 3 247 3 262 3 220 3 247 3 196 3 220 3 220 3 262 3 262 3 294 3 262 3 247 3 220 3 196 3 247 3 262 3 247 5 220 1 220 5"

Tango-edit-cut.pngThis section is being considered for removal.Tango-edit-cut.png

Reason: Common samples should be listed elsewhere, there should be just a link. (Discuss in Talk:GRUB/Tips and tricks#)

You can add a menu entry to play each of these common GRUB_INIT_TUNE samples by creating the following file and then re-running grub-mkconfig.

/etc/grub.d/91_tune_demo
#!/bin/sh
exec tail -n +3 $0
menuentry "INIT_TUNE Demos" {
   echo "Close Encounters/5 Tone"
   play 480 900 2 1000 2 800 2 400 2 600 3
   echo "Fur Elise (note long)"
   play 480 420 1 400 1 420 1 400 1 420 1 315 1 370 1 335 1 282 3 180 1 215 1 282 1 315 3 213 1 262 1 315 1 335 3 213 1 420 1 400 1 420 1 400 1 420 1 315 1 370 1 335 1 282 3 180 1 215 1 282 1 315 3 213 1 330 1 315 1 282 3
   echo "Berlioz's extract from Sabbath Night of Symphonie Fantastique"
   play 312 262 3 247 3 262 3 220 3 247 3 196 3 220 3 220 3 262 3 262 3 294 3 262 3 247 3 220 3 196 3 247 3 262 3 247 5 220 1 220 5
   echo "Oldskool Batman tune"
   play 380 120 1 140 1 160 1 200 8 190 4
   echo "Legend of Zelda tune"
   play 12000 440 100 0 1 329 150 440 50 0 1 440 25 493 25 523 25 587 25 659 200
   echo "Super Mario"
   play 1000 334 1 334 1 0 1 334 1 0 1 261 1 334 1 0 1 392 2 0 4 196 2
   echo "Super Mario Alternate"
   play 480 165 2 165 2 165 3 554 1 587 1 554 2 370 1 554 1 523 2 349 1 523 1 494 3 165 2 165 2 165 2
   echo "Mario Mushroom"
   play 1750 523 1 392 1 523 1 659 1 784 1 1047 1 784 1 415 1 523 1 622 1 831 1 622 1 831 1 1046 1 1244 1 1661 1 1244 1 466 1 587 1 698 1 932 1 1175 1 1397 1 1865 1 1397 1
   echo "Star Wars Imperial Death March"
   play 480 440 4 440 4 440 4 349 3 523 1 440 4 349 3 523 1 440 8 659 4 659 4 659 4 698 3 523 1 415 4 349 3 523 1 440 8
   echo "My Little Pony"
   play 2400 587 18 554 4 587 8 659 12 587 16 0 10 587 4 659 4 740 8 587 4 784 12 740 8 659 8 587 4 740 20 587 40
   echo "Wolfenstein 3D"
   play 300 131 1 196 1 196 1 196 1 294 1 196 1 294 1 196 1 131 1
   echo "Mall (Nothing Special)"
   play 180 440 1 554 1 659 1
   echo "Final Countdown"
   play 480 554 1 494 1 554 4 370 6 10 3 587 1 554 1 587 2 554 2 494 6
   echo "Xie-Jelei's Tune"
   play 2000 400 4 0 1 500 4 0 1 600 4 0 1 800 6
   echo "Random tune"
   play 480 220 1 277 1 330 1 440 1 185 1 220 1 277 1 370 1 294 1 370 1 440 1 587 1 330 1 415 1 494 1 659 1
   echo "Fleetwood Mac: The Chain Bass Riff (about 5 seconds)"
   play 304 55 5 0 1 55 1 62 1 65 2 62 1 55 1 49 1 55 1 62 2 41 8
   echo "Fleetwood Mac: The Chain Bass Riff Extended Version (WARNING, 25 SECONDS)"
   play 9120 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 120 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 60 41 12 42 3 43 3 44 3 45 3 46 6 47 3 48 3 49 6 50 3 51 3 52 6 53 3 54 3 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 240 82 20 0 10 82 26 0 4 82 26 0 4 82 26 0 4 82 56 0 4 82 60 55 150 0 30 55 30 62 30 65 60 62 30 55 30 49 30 55 30 62 60 41 360 0 120
}

For information on this, you can look at info grub -n play.

Manual configuration of core image for early boot

If you require a special keymap or other complex steps that GRUB is not able to configure automatically in order to make /boot available to the GRUB environment, you can generate a core image yourself. On UEFI systems, the core image is the grubx64.efi file that is loaded by the firmware on boot. Building your own core image will allow you to embed any modules required for very early boot, as well as a configuration script to bootstrap GRUB.

Firstly, taking as an example a requirement for the dvorak keymap embedded in early-boot in order to enter a password for a crypted /boot on a UEFI system:

Determine from the generated /boot/grub/grub.cfg file what modules are required in order to mount the crypted /boot. For instance, under your menuentry you should see lines similar to:

insmod diskfilter cryptodisk luks gcry_rijndael gcry_rijndael gcry_sha256
insmod ext2
cryptomount -u 1234abcdef1234abcdef1234abcdef
set root='cryptouuid/1234abcdef1234abcdef1234abcdef'

Take note of all of those modules: they'll need to be included in the core image. Now, create a tarball containing your keymap. This will be bundled in the core image as a memdisk:

# grub-kbdcomp -o dvorak.gkb dvorak
# tar cf memdisk.tar dvorak.gkb

Now create a configuration file to be used in the GRUB core image. This is in the same format as your regular grub config, but need contain only a few lines to find and load the main config file on the /boot partition:

early-grub.cfg
set root=(memdisk)
set prefix=($root)/

terminal_input at_keyboard
keymap /dvorak.gkb

cryptomount -u 1234abcdef1234abcdef1234abcdef
set root='cryptouuid/1234abcdef1234abcdef1234abcdef'
set prefix=($root)/grub

configfile grub.cfg

Finally, generate the core image, listing all of the modules determined to be required in the generated grub.cfg, along with any modules used in the early-grub.cfg script. The example above needs memdisk, tar, at_keyboard, keylayouts and configfile.

# grub-mkimage -c early-grub.cfg -o grubx64.efi -O x86_64-efi -m memdisk.tar diskfilter cryptodisk luks gcry_rijndael gcry_sha256 ext2 memdisk tar at_keyboard keylayouts configfile

The generated EFI core image can now be used in the same way as the image that is generated automatically by grub-install: place it in your EFI partition and enable it with efibootmgr, or configure as appropriate for your system firmware.

UEFI further reading

Tango-edit-clear.pngThis article or section needs language, wiki syntax or style improvements. See Help:Style for reference.Tango-edit-clear.png

Reason: This could be made more concise, better organized. (Discuss in Talk:GRUB/Tips and tricks#)

Below is other relevant information regarding installing Arch via UEFI.

Alternative install method

Usually, GRUB keeps all files, including configuration files, in /boot, regardless of where the EFI System Partition is mounted.

If you want to keep these files inside the EFI System Partition itself, add --boot-directory=esp to the grub-install command:

# grub-install --target=x86_64-efi --efi-directory=esp --bootloader-id=grub --boot-directory=esp --debug

This puts all GRUB files in esp/grub, instead of in /boot/grub. When using this method, make sure you have grub-mkconfig put the configuration file in the same place:

# grub-mkconfig -o esp/grub/grub.cfg

Configuration is otherwise the same.

UEFI firmware workaround

Tango-edit-cut.pngThis section is being considered for removal.Tango-edit-cut.png

Some UEFI firmware requires that the bootable .efi stub have a specific name and be placed in a specific location: esp/EFI/boot/bootx64.efi (where esp is the UEFI partition mountpoint). Failure to do so in such instances will result in an unbootable installation. Fortunately, this will not cause any problems with other firmware that does not require this.

To do so, first create the necessary directory, and then copy across the grub .efi stub, renaming it in the process:

# mkdir esp/EFI/boot
# cp esp/EFI/grub_uefi/grubx64.efi esp/EFI/boot/bootx64.efi

Create a GRUB entry in the firmware boot manager

grub-install automatically tries to create a menu entry in the boot manager. If it does not, then see UEFI#efibootmgr for instructions to use efibootmgr to create a menu entry. However, the problem is likely to be that you have not booted your CD/USB in UEFI mode, as in UEFI#Create UEFI bootable USB from ISO.

GRUB standalone

This section assumes you are creating a standalone GRUB for x86_64 systems (x86_64-efi). For 32-bit (IA32) EFI systems, replace x86_64-efi with i386-efi where appropriate.

It is possible to create a grubx64_standalone.efi application which has all the modules embedded in a tar archive within the UEFI application, thus removing the need to have a separate directory populated with all of the GRUB UEFI modules and other related files. This is done using the grub-mkstandalone command (included in grub) as follows:

# echo 'configfile ${cmdpath}/grub.cfg' > /tmp/grub.cfg
# grub-mkstandalone -d /usr/lib/grub/x86_64-efi/ -O x86_64-efi --modules="part_gpt part_msdos" --locales="en@quot" --themes="" -o "esp/EFI/grub/grubx64_standalone.efi" "boot/grub/grub.cfg=/tmp/grub.cfg" -v

Then copy the GRUB config file to esp/EFI/grub/grub.cfg and create a UEFI Boot Manager entry for esp/EFI/grub/grubx64_standalone.efi using efibootmgr.

Note: The option --modules="part_gpt part_msdos" (with the quotes) is necessary for the ${cmdpath} feature to work properly.
Warning: You may find that the grub.cfg file is not loaded due to ${cmdpath} missing a slash (i.e. (hd1,msdos2)EFI/Boot instead of (hd1,msdos2)/EFI/Boot) and so you are dropped into a GRUB shell. If this happens determine what ${cmdpath} is set to (echo ${cmdpath} ) and then load the config file manually (e.g. configfile (hd1,msdos2)/EFI/Boot/grub.cfg).

Technical information

The GRUB EFI file always expects its config file to be at ${prefix}/grub.cfg. However in the standalone GRUB EFI file, the ${prefix} is located inside a tar archive and embedded inside the standalone GRUB EFI file itself (inside the GRUB environment, it is denoted by "(memdisk)", without quotes). This tar archive contains all the files that would be stored normally at /boot/grub in case of a normal GRUB EFI install.

Due to this embedding of /boot/grub contents inside the standalone image itself, it does not rely on actual (external) /boot/grub for anything. Thus in case of standalone GRUB EFI file ${prefix}==(memdisk)/boot/grub and the standalone GRUB EFI file reads expects the config file to be at ${prefix}/grub.cfg==(memdisk)/boot/grub/grub.cfg.

Hence to make sure the standalone GRUB EFI file reads the external grub.cfg located in the same directory as the EFI file (inside the GRUB environment, it is denoted by ${cmdpath} ), we create a simple /tmp/grub.cfg which instructs GRUB to use ${cmdpath}/grub.cfg as its config (configfile ${cmdpath}/grub.cfg command in (memdisk)/boot/grub/grub.cfg). We then instruct grub-mkstandalone to copy this /tmp/grub.cfg file to ${prefix}/grub.cfg (which is actually (memdisk)/boot/grub/grub.cfg) using the option "boot/grub/grub.cfg=/tmp/grub.cfg".

This way, the standalone GRUB EFI file and actual grub.cfg can be stored in any directory inside the EFI System Partition (as long as they are in the same directory), thus making them portable.