GRUB 2 runs a series of scripts which search the user's computer and builds a boot menu based on what operating systems it finds. The scripts are highly configurable and produce a menu which requires little user input. When new kernels are added or the system is updated, GRUB 2 automatically rebuilds the menu to keep it current and to reflect the latest system boot options.

Nevertheless, users may want to build a menu, or part of a menu, which does not change or which allows specific inputs not easily attained via the scripts. Others may want a menu which more closely follows the way GRUB 0.97 operated. GRUB 2's custom menus allow the system to provide the basic building blocks of the boot menu while allowing the user to control what actually appears on the screen. This page details how to build and incorporate custom menus into the GRUB 2 menu.

  • g2_custom_menu.png

Uses of a Custom Menu

Custom menus offer many benefits over the default GRUB 2 menu. Some of the advantages include:

  • The menu only changes when the user edits it.
    • Kernel and system updates will not change the position or options of a menu item.
  • Menuentry titles are easily editable.
  • Items are easily placed in any order on the menu.
  • Password protection for specific entries rather than an entire class of operating systems can be made.

Disadvantages include:

  • Lack of automatic updates, depending on how the custom menu is constructed.
  • Loss of input of some user preferences from the /etc/default/grub file.

Menu Creation Background

GRUB 2 constructs the menu via a series of scripts, with each script building a portion of the menu. These scripts include /etc/grub.d/00_header and /etc/grub.d/05_header. The GRUB 2 menu configuration file (grub.cfg) includes section remarks showing which script is responsible for creating the section. The /etc/default/grub file contains most of the user-defined variables such as display time, menu resolution and default menuentry. Most custom menu users will want to allow these components to continue to operate normally.

The two scripts which actually place items into the menu are /etc/grub.d/10_linux, which locates kernels in the default Ubuntu partition, and /etc/grub.d/30_os-prober, which builds entries for operating systems found on other partitions.

For information on these files/folders please refer to the Grub2 page.

Building a Custom Menu

A sample custom menu called 40_custom is provided in the /etc/grub.d/ folder. This file can be used or copied. The current 40_custom file contains only lines which are not actually imported into grub.cfg. In general, users should honor the comments and leave these lines alone, adding custom entries below the existing lines.

  • g2_custom_header.png

The surest way to build a custom menu is to copy one or more working menuentries from the grub.cfg file. Menuentries can be placed in any order. As a minimum, a valid menuentry should include:

  • menuentry "Some title here" {

    <Some data>


GRUB 2 features such as Passwords and Submenus work in custom menus. If the user doesn't wish to password-protect all menuentries, the custom menu is an easy way to designate only some of the entries while still allowing the GRUB 2 scripts to operate normally. Click the links to visit the community documentation regarding these topics.

General Menuentry Construction Rules

  • The first line must start with menuentry and end with {

    • The area between the quotation marks is what will appear on the GRUB 2 menu. Edit as desired.
  • The last line of the menuentry must be }

  • Do not leave empty spaces at the end of lines

  • The set root= line should point to the GRUB 2 /boot location ( (hdX,Y) )

  • The search line's --set has been replaced in GRUB 1.99 (Ubuntu 11.04 and later) with --set=root

    • Using "--set" rather than "--set=root" in GRUB 1..99 will result in an "error: no argument specified" message.

  • The root reference in in the linux line should point to the system partition.

    • If GRUB 2 cannot find the referenced kernel, try replacing the UUID with the device name (example: /dev/sda6 ).

Custom Menu Naming

info.png The name of the file is important in that the filename number determines its position in the final GRUB 2 menu. By default, the file contents will be placed at the bottom of the GRUB 2 menu since it is run last - after 10_linux, 20_memtest86+, and 30_os-prober. If desired, the 40_custom file can be renamed to place it elsewhere in the menu:

  • 06_custom would be contain the first menu items.
    • Do not name it less than 06 to ensure 05_debian theme runs first.

  • 15_custom entries would follow the active Ubuntu partition's entries but be before MEMTEST86+ and other operating systems.
  • Executable scripts beginning with a letter (e.g. my_menu) will run after all scripts starting with a numeral.

  • If copying the 40_custom file, the executable bit should remain set. If the script doesn't run, ensure the file is still executable by checking its Properties in a file browser or running sudo ls -la /etc/grub.d/XX_custom

Sample Menuentries

  • A sample entry copied from the grub.cfg and altered by the user might look like this *:

    • menuentry "My Default Precise" {


      gfxmode $linux_gfx_mode

      insmod gzio

      insmod part_msdos

      insmod ext2

      set root='(hd0,msdos9)'

      search --no-floppy --fs-uuid --set=root dbd69ed2-530c-4409-8f5a-a3f1ea41fc67

      linux /boot/vmlinuz-3.2.0-24-generic root=UUID=dbd69ed2-530c-4409-8f5a-a3f1ea41fc67 ro quiet splash $vt_handoff

      initrd /boot/initrd.img-3.2.0-24-generic


      * For GRUB 1.98 (Lucid) and earlier, the search line is modified:

      search --no-floppy --fs-uuid --set-root=dbd69ed2-530c-4409-8f5a-a3f1ea41fc67

  • A sample entry for a hard drive version of SystemRescueCD installed per the instructions on the web site (on sda8).
    • menuentry "System Rescue CD" {

      set root=(hd0,8)

      linux /sysrcd/rescuecd subdir=sysrcd setkmap=us

      initrd /sysrcd/initram.igz


  • A sample entry for Windows.
    • menuentry "Windows 7" {

      insmod ntfs

      set root='(hd0,1)'

      search --no-floppy --fs-uuid --set a3f1ea41fc67a3f1

      chainloader +1


  • A sample entry for chainloading to another GRUB bootloader.
    • menuentry "Grub 1 Bootloader" {

      set root=(hd0,8)

      chainloader +1


Maintenance-Free Menuentries

There is a potential drawback of a custom menu when the 10_linux and/or 30_os-prober scripts have been disabled. A copied Linux menuentry normally contains a specific kernel and initrd image version number (such as 3.2.0-24) and will not change if a new kernel is introduced.

If the user wishes to always boot the current kernel, the linux and initrd lines of the can take advantage of the symlinks placed in /. These links always point to the most recent kernel. If they are referenced in the menuentry and the symlinks exist, the menuentry will always point to the latest kernel.

Replace the normal linux and initrd references, which normally contain the complete kernel version, with the following:

  • linux /vmlinuz root=UUID=dbd69ed2-530c-4409-8f5a-a3f1ea41fc67 ro quiet splash $vt_handoff{

    initrd /initrd.img

If the user wishes to use a generic menuentry to always have the current kernel available without updating the menu, consider placing a known working kernel in another menuentry as a backup. Alternatively, learn how to edit the menuentry while booting to be able to alter it to an older kernel.

important.png If the user intends to allow automatic booting, consider:

  • If other scripts (10_linux or 30_os-prober) are enabled, a "maintenance-free" custom menu name should start with a value of 06 to 09 (e.g. 06_custom). This will ensure the menuentries are always the first ones on the menu, no matter how many additional entries the other scripts add to the menu.

  • The "GRUB_DEFAULT=" setting in /etc/default/grub must be set to point to the 'generic' menuentry. Since the custom menu will always be first in the GRUB 2 menu if the above naming convention is used, the position in the menu for the generic entry will not change. It need not be the first entry, but the GRUB_DEFAULT number should match if you want to boot the latest kernel. The first menu item is 0, the second is 1, etc.

  • Run sudo update-grub to update the menu.

Using GRUB Legacy Menuentries

  • The following entries from the GRUB menu listing must be changed for them to work:
    • title is changed to menuentry. The line must end with {

    • root is changed to set root= (GRUB 1.99 or later)

    • kernel must be changed to linux

    • Any partition designation ((hd0,4), (hd1,6)) must be changed, as GRUB and GRUB 2 count the partitions differently. The first partition for GRUB 2 is 1, not 0. Devices still start the count at 0.

    • Look carefully at the format of any working GRUB 2 menulist entry to ensure the correct format is used.

Removing Default Script Entries

The custom menu can be used to replace either or both of the 10_linux and 30_os-prober scripts. To disable a script remove the "executable" bit by changing the Properties in a file browser run as 'root' or by running the following command on one or both of the files:

  • sudo chmod -x /etc/grub.d/10_linux /etc/grub.d/30_os-prober

The user may also turn off the 30_os-prober script via the GRUB 2 settings file - /etc/default/grub. Add this item to the file, save it, and run sudo update-grub.


Using Only a Custom Menu

The following is one example of a way to use only a custom menu and not receive any automatic menuentry updates:

  • Copy/paste the entire contents of your /boot/grub/grub.cfg file into the /etc/grub.d/40_custom file, below the existing header lines.

    • #!/bin/sh

      exec tail -n +3 $0

      # This file provides an easy way to add custom menu entries. Simply type the

      # menu entries you want to add after this comment. Be careful not to change

      # the 'exec tail' line above.

  • Remove everything above the first menuentry except the existing header lines above.
  • Remove all but the following files from the /etc/grub.d folder:

    • 00_header, 05_debian_theme, 40_custom and README.

    • Alternatively, you may keep other files in the /etc/grub.d folder if you make them unexecutable.

  • Edit, add, or remove menuentries as desired, then save the file.
  • Run update-grub as root to apply the changes!









Grub2/CustomMenus (last edited 2012-11-04 00:59:58 by par1346)