Where can I find GRUB bootloader script before the system is started up? I'm running on VBox V4.3.12 r93733.

  • What do you mean "bootloader script"? The actual code? The config data? Where the bootloader is on the hard drive?
    – Kaz Wolfe
    Aug 27, 2014 at 4:12
  • When we first started up the machine, it will prompt us to choose 'Ubuntu' or 'Advanced options for Ubuntu' or 'Memory test' and so on from GNU GRUB. I'd like to know where is this GRUB script file actually stored onto before it's started up?
    – navorser
    Aug 27, 2014 at 4:31
  • So the config file that gives the boot menu options?
    – Kaz Wolfe
    Aug 27, 2014 at 4:35
  • You may say so.
    – navorser
    Aug 27, 2014 at 4:36

2 Answers 2


If I understood you right, you want the location of the bootloader config file that you can manually edit.

There are a few different locations where these files are stored.

  • Main config: /etc/default/grub <-- This is the one you really want to edit. OK to play.
  • Grub config files: /etc/grub.d <-- Custom boot entries. Semi-OK to play.
  • Various other things: /boot <-- Don't play with things in this dir.

The file that is ACTUALLY read by GRUB2 is stored somewhere on the "boot" partition (EFI, boo!) and/or the empty sectors at the beginning of the hard drive (Legacy, yay!). [I think]

  • If I understand it correctly, these files in /etc/default/,/etc/grub.d, /boot will only be readable once /boot and / have been mounted which is after vmlinuz kernel and initrd have been successfully loaded. My doubt is that even before /boot and / are mounted where is this GNU GRUB script file residing, where we can see GNU GRUB menu to choose 'Ubuntu' or 'Advanced options for Ubuntu' or 'Memory test' and so on from GNU GRUB menu?
    – navorser
    Aug 27, 2014 at 5:41
  • @navorser Bottom part of answer
    – Kaz Wolfe
    Aug 27, 2014 at 5:56
  • @navorser The original Grub, now called 'Grub Legacy' had a menu file that was easy to edit. Ubuntu uses the current incarnation of Grub, Grub2. It spreads the pieces out and is significantly more complex. It does not have a single menu file. Aug 27, 2014 at 5:59
  • When I checked the script of GNU GRUB Menu before executing any bootup menu, I found that it's the same script as its /boot/grub/grub.cfg
    – navorser
    Aug 27, 2014 at 7:33
  • Thanks to Mew and ben. I am wondering where does this script from the quote come from since partition of the storage on the machine haven't been mounted yet?"setparams 'Ubuntu' recordfail load_video gfxmode $linux_gfx_mode insmod gzio insmod part_msdos insmod ext2 set root='hd0,msdos1' if [X$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1\ --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 7b31bb31-630f-42bb\ -b091-00503d5e2deb else search --no-floppy --fs-uuid --set=root 7b31bb31-630f-42bb-b09\ 1-00503d5e2deb fi"
    – navorser
    Aug 27, 2014 at 8:09

---Grub 2 Files & Options

  Grub 2 is modular and these files are loaded as necessary by the grub bootloader.

  The Grub 2 user-configurable settings are contained mainly in /etc/default/grub and the files in /etc/grub.d. When update-grub is executed the results are input into the /boot/grub/grub.cfg file.

      x /boot/grub/grub.cfg

            - This is the main Grub 2 file. This file contains the Grub menu information but unlike Grub Legacy's menu.lst file, grub.cfg is not meant to be edited.

                  + grub.cfg is automatcially generated when "update-grub" is executed:

                  + Each section (### BEGIN) is clearly delineated and references the file in the /etc/grub.d folder from which the information was generated.

                  + grub.cfg is updated by running the "update-grub2" or "update-grub" command as root.

                  + By default, and whenever the "update-grub2" command is executed, this file is made "read-only". This is in keeping with the intent that the file should not be edited manually. If you must edit this file, instructions are provided in Section 2.

            - Sample grub.cfg including Windows and one manual entry (41_srcd):


              # DO NOT EDIT THIS FILE
              # It is automatically generated by /usr/sbin/grub-mkconfig using templates
              # from /etc/grub.d and settings from /etc/default/grub

              ### BEGIN /etc/grub.d/00_header ###
              set default="0"
              if [ ${prev_saved_entry} ]; then
                save_env saved_entry
                save_env prev_saved_entry
              insmod ext2
              set root=(hd0,1)
              search --no-floppy --fs-uuid --set 7ebcfe33-6914-42ec-9d2e-0859f7396925
              if loadfont /usr/share/grub/unicode.pf2 ; then
                set gfxmode=640x480
                insmod gfxterm
                insmod vbe
                if terminal_output gfxterm ; then true ; else
                  # For backward compatibility with versions of terminal.mod that don't
                  # understand terminal_output
                  terminal gfxterm
              if [ ${recordfail} = 1 ]; then
                set timeout=-1
                set timeout=10
              ### END /etc/grub.d/00_header ###

              ### BEGIN /etc/grub.d/10_linux ###
              menuentry "Ubuntu, Linux 2.6.31-12-generic" {
                      save_env recordfail
                  set quiet=1
                  insmod ext2
                  set root=(hd0,1)
                  search --no-floppy --fs-uuid --set 7ebcfe33-6914-42ec-9d2e-0859f7396933
                  linux    /boot/vmlinuz-2.6.31-12-generic root=UUID=7ebcfe33-6914-42ec-9d2e-0859f7396933 ro   quiet splash
                  initrd    /boot/initrd.img-2.6.31-12-generic
              menuentry "Ubuntu, Linux 2.6.31-12-generic (recovery mode)" {
                      save_env recordfail
                  insmod ext2
                  set root=(hd0,1)
                  search --no-floppy --fs-uuid --set 7ebcfe33-6914-42ec-9d2e-0859f7396933
                  linux    /boot/vmlinuz-2.6.31-12-generic root=UUID=7ebcfe33-6914-42ec-9d2e-0859f7396933 ro single 
                  initrd    /boot/initrd.img-2.6.31-12-generic
              menuentry "Ubuntu, Linux 2.6.31-11-generic" {
                      save_env recordfail
                  set quiet=1
                  insmod ext2
                  set root=(hd0,1)
                  search --no-floppy --fs-uuid --set 7ebcfe33-6914-42ec-9d2e-0859f7396933
                  linux    /boot/vmlinuz-2.6.31-11-generic root=UUID=7ebcfe33-6914-42ec-9d2e-0859f7396933 ro   quiet splash
                  initrd    /boot/initrd.img-2.6.31-11-generic
              menuentry "Ubuntu, Linux 2.6.31-11-generic (recovery mode)" {
                      save_env recordfail
                  insmod ext2
                  set root=(hd0,1)
                  search --no-floppy --fs-uuid --set 7ebcfe33-6914-42ec-9d2e-0859f7396933
                  linux    /boot/vmlinuz-2.6.31-11-generic root=UUID=7ebcfe33-6914-42ec-9d2e-0859f7396933 ro single 
                  initrd    /boot/initrd.img-2.6.31-11-generic
              ### END /etc/grub.d/10_linux ###

              ### END /etc/grub.d/20_memtest86+ ###

              ### BEGIN /etc/grub.d/30_os-prober ###
              menuentry "Microsoft Windows XP Home Edition (on /dev/sda1)" {
                  set root=(hd0,1)
                  chainloader +1
              ### END /etc/grub.d/30_os-prober ###

              ### BEGIN /etc/grub.d/40_custom ###
              menuentry "Jaunty 2.6.28-15-custom" {
                  save_env saved_entry
                  set root=(hd0,8)
                  linux    /boot/vmlinuz-2.6.28-15-custom root=UUID=48e03255-22b3-488b-ae7e-9dbe4e2beac7 ro  quiet splash
                  initrd    /boot/initrd.img-2.6.28-15-custom
              menuentry "SystemRescue" {
                  save_env saved_entry
                      set root=(hd0,6)
                      linux   /sysrcd/rescuecd subdir=sysrcd setkmap=us
                      initrd  /sysrcd/initram.igz
              ### END /etc/grub.d/40_custom ###

      x /etc/default/grub

            - This file contains information formerly contained in the upper section of Grub Legacy's menu.lst and items contained on the end of the kernel line. The items in this file can be edited by a user with administrator (root) privileges.

              # If you change this file, run 'update-grub' afterwards to update
              # /boot/grub/grub.cfg.

              GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
              GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

              # Uncomment to disable graphical terminal (grub-pc only)

              # The resolution used on graphical terminal
              # note that you can use only modes which your graphic card supports via VBE
              # you can see them in real GRUB with the command `vbeinfo'

              # Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux

              # Uncomment to disable generation of recovery mode menu entrys

            - A few bugs still exist in the hidden menu feature. Hiding the menu, even with the correct "TIMEOUT" settings in /etc/default/grub may not work as described.

            - GRUB_DEFAULT - Sets the default menu entry. Entries may be numeric or "saved"

                  + GRUB_DEFAULT=0 - Sets the default menu entry by menu position. As Grub Legacy, the first "menuentry" in grub.cfg is 0, the second is 1, etc.

                  + GRUB_DEFAULT=saved - Sets the default menu entry with whatever was selected last. If the menu is displayed during boot, the last entry selected will be highlighted. If no action is taken, this selection will be booted at the end of the timeout or if the menu is hidden.

                        # grub-set-default is enabled when this value is set to saved. You can quickly change the default OS/kernel with this command.

                              * The format is "sudo grub-set-default X, with X being the menuentry position (starting with 0 as the first entry) or the exact menu string. Examples: sudo grub-set-default 3 or sudo grub-set-default "Ubuntu, Linux 2.6.31-14-generic"

                              * To obtain the existing menuentry choice number (starting from 0) or the menuentry "string", run "grep menuentry /boot/grub/grub.cfg"

                  + GRUB_DEFAULT="xxxx" - An exact menu entry, including the quotation symbols, may also be used. In this case, location in the menu will not matter. Example: GRUB_DEFAULT="Ubuntu, Linux 2.6.31-9-generic"

                  + For an example of how to enable the "saved" option with a custom menu, see the "Custom User Entries" section.

            - GRUB_TIMEOUT=5 - No change from Grub Legacy. This is the number of seconds before the default entry is automatically booted.

                  + Setting this value to -1 will cause the menu to display until the user makes a selection.

                  + To display the menu on each boot use a value of 1 or higher.

                  + This command defers to the GRUB_HIDDEN_TIMEOUT command. If the hidden display is interrupted by a key press, the GRUB_TIMEOUT counter begins its countdown.

                  + In addition to editing the file as root, you can also run the following commands the check and change the default timeout value. The first checks the existing timeout, the second replaces the value. Replace T with the new value.


                    cat /etc/default/grub | grep 'GRUB_TIMEOUT='   # Checks current TIMEOUT value.
                    sudo sed 's/GRUB_TIMEOUT=5/GRUB_TIMEOUT=T/g' -i /etc/default/grub  # Change TIMEOUT value. Replace T with new value.

            - GRUB_HIDDEN_TIMEOUT=0

                  + The menu will be hidden unless a # symbol is present at the beginning of this line. ( # GRUB_HIDDEN_TIMEOUT=0 )

                  + The setting may depend on the presence of other operating systems.

                        # Another OS Detected: The menu will be displayed. ( The line will begin with a # symbol. )

                        According to some of the GRUB 2 developers, in Ubuntu the menu will not be hidden any time there are other OSs found by os-prober, regardless of this setting. This is in keeping with the Ubuntu Team's goal towards booting: https://wiki.ubuntu.com/DesktopExper...pec#Bootloader

                        # No other OS Detected: The menu will be hidden.

                  + For integers greater than 0, the system will pause, but not display the menu, for the entered number of seconds.

                  + 0 The menu will not be displayed. There will be no delay. When this entry is set to 0:

                        # The user may force displaying the menu as the computer boots by holding down the SHIFT key.

                        # During boot, the system will check the SHIFT key status. If it cannot determine the key status, a short delay will enable the user to display the menu by pressing the ESC key.

                  + If enabled, the splash screen designated in 05_debian_theme will be displayed. This setting hides the menu only.

            - GRUB_HIDDEN_TIMEOUT_QUIET=true

                  + true - No countdown is displayed. The screen will be blank.

                  + false - A counter will display on a blank screen for the duration of the GRUB_HIDDEN_TIMEOUT value.

            - GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
                  + Determines the descriptive name in the menu entry. (Ubuntu, Xubuntu, Debian, etc.)

            - GRUB_CMDLINE_LINUX

              If it exists, this line imports any entries to the end of the 'linux' command line (Grub Legacy's "kernel" line) for both normal and recovery modes. This is similar to the "altoptions" line in menu.lst

            - GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
              This line imports any entries to the end of the 'linux' line (Grub Legacy's "kernel" line). The entries are appended to the end of the normal mode only. This is similar to the "defoptions" line in menu.lst. For a black screen with boot processes displayed in text, remove "quiet splash". To see the grub splash image plus a condensed text output, use "splash". This line is where other instructions, such as "acpi=off" are placed.

            - #GRUB_TERMINAL=console

              Uncomment to disable graphical terminal (grub-pc only). This can be useful if the user plans on spending a lot of time in the GRUB 2 command line mode. Scrolling and screen responsiveness will be greatly speeded up.

            - #GRUB_DISABLE_LINUX_UUID=true

              Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux

            - #GRUB_GFXMODE=640x480

              You can add this line and remove the # symbol to make it active. This entry sets the resolution of the graphical menu (the menu text size). It provides resolutions supported by the user's graphics card (e.g. 640x480, 800x600, 1280x1024, etc). The setting applies only to the boot menu text.

            - From the GRUB 2 menu you can display available resolutions by typing "c" and then at the "grub>" prompt type "vbeinfo"


              Add or uncomment this line to prevent "Recovery" mode kernel options from appearing in the menu. If you want a "Recovery" option for only one kernel, make a special entry in /etc/grub/40_custom.

            - GRUB_DISABLE_OS_PROBER="true" - Enables/disables the os-prober check of other partitions for operating systems, including Windows, Linux, OSX and Hurd.

      x /etc/grub.d/

            - The files in this folder are read during execution of "update-grub" or "update-grub2" commands. The contents are imported into /boot/grub/grub.cfg

              The order of the entries in the grub menu is based on the order of the file names. File named with a starting numeral are run before those beginning with a letter. The order the files are run determines the menu order in grub.cfg.
              Custom entries can be added to the "40_custom" file or in a newly created file.

              Any file created must be executable in order to be included in the grub.cfg file during the "update-grub2" command.
                  + 00_header
                  + 05_debian_theme: Set background and text colors, themes
                  + 10_hurd Locates Hurd kernels
                  + 10_linux Locates Linux kernels based on results of the "lsb_release" command.
                  + 20_memtest86+: If the file /boot/memtest86+.bin exists, it is included as a menu item.
                  + 30_os-prober: Searches for Linux and OS's on other partitions and includes them in the menu.
                  + 40_custom: A template for adding custom menu entries which will be inserted into grub.cfg upon execution of the "update-grub2" command. This and any other custom file must be made executable to allow importation into grub.cfg.

---Adding Entries to Grub 2

  Menu entries can be added to grub.cfg automatically or manually.

      x Automatically.

            - When "update-grub" or "update-grub2" is executed, Grub 2 will search for linux kernels and other Operating Systems. What and where is looks is based on the files contained in /etc/grub.d folder.
                  + 10_linux searches for installed linux kernels on the same partition.
                  + 30_os-prober searches for other operating systems.

      x Custom User Entries (/etc/grub.d/40_custom).

            - Entries to grub.cfg can be manually inserted by creating a file in the /etc/grub.d folder.
                  + The name of the file determines the order in the menu. 30_os-prober entries will be placed before 40_custom entries, which will be placed before 50_my-sample entries.
                  + Any created file must be made executable. This can be done as root by running "sudo chmod +x /etc/grub.d/filename".
                  + The files in the /etc/grub.d folder will be read and the contents included in grub.cfg when the "update-grub2" command is executed as root.

            - A sample entry. This file creates a menu item for running the SystemRescueCD (previously installed) from a partition created on sda10. Folders and files must have been copied to the correct location in accordance with the SystemRescueCD if you wish to actually use this entry.

                    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.

                    echo "Adding SystemRescueCD" >&2
                    menuentry "System Rescue CD" {
                    set root=(hd0,10)
                    linux /sysrcd/rescuecd subdir=sysrcd setkmap=us
                    initrd /sysrcd/initram.igz

                  + Note the new partition naming convention. Devices start counting from "0" as done previously. sda is designated as "hd0", sdb is "hd1", etc. However the first partition is now designated as sda1. Counting partitions does not start with "0". sda5 is "5".
                  + The line 'echo "Adding SystemRescueCD" >&2' is not required. Including it in the file allows this line to be seen in the terminal when "update-grub2" is executed. It provides visual feedback that the entry has been found and entered. The entry, if in the correct format, will be inserted in grug.cfg whether or not this line is included in the file.

            - Tip: If you want to have your custom entries at the top of the menu (say you want custom titles), create a new file and name it "07_xxxx". Since the files in /etc/grub.d/ are read sequentially, those in "07_custom" will be placed before those of "10_linux". I recommend not naming a custom menu file lower than 06 so that any theme run from 05_debian_theme is allowed to run before any custom menu is created. After creating the file, run sudo update-grub and then check the value of "DEFAULT" in /etc/default/grub. If it doesn't point to the correct menuentry, change the value of DEFAULT to the correct menuentry value.

            - Omitting memtest86+: To prevent "memtest86+" entries in your Grub 2 menu, remove the "executable" bit from /etc/grub.d/20_memtest86+. You can do this via a file browser by selecting "Properties (right click), Permissions", or via the command line:

              sudo chmod -x /etc/grub.d/20_memtest86+

            - Omitting Recovery Mode entries: The file /etc/grub.d/10_linux was recently updated to include a check for recovery mode options. Edit /etc/default/grub and add or change this line:

              If you have an older version of /etc/grub.d/10_linux and the above does not work after updating grub, you can prevent "Recovery mode" entries in your Grub 2 menu, by editing /etc/grub.d/10_linux. If there are no conditional "if" statements concerning the recovery mode, place a comment symbol (#) in front of the following lines (at approximately line 146) of the old file:

              # linux_entry "${OS}, Linux ${version} (recovery mode)" \
              # "single ${GRUB_CMDLINE_LINUX}"
              If you wish to retain one "Recovery mode" entry for insurance, you can add an entry to /etc/grub.d/40_custom which will appear at the bottom of your grub menu.

            - Building a Totally Customized Menu: Ok, admit you are a control freak and you want to see only what you build yourself - customized titles, no "memtest86+" and no extra kernels. Here is how you do it:
                  + Run sudo update-grub to get the current available kernels.
                  + Copy the desired "menuentry" listings from /boot/grub/grub.cfg to /etc/grub.d/40_custom The entry begins with the line starting with "menuentry" and ends with a line containing "}".
                  + Add any other "menuentry" items you wish to see on the boot menu.
                  + Edit the titles of the "menuentry" line if desired (between the quotation symbols). Do not change the lines following the "menuentry" line. Each entry should start with a "menuentry" line and end with a "}" on the last line.
                  + Remove the executable bit from /etc/grub.d/10_linux, /etc/grub.d/20_memtest86+ and /etc/grub.d/30_os-prober
                    Removing the executable bit from any file in /etc/grub.d will exclude the file from being included in grub updates.

                    sudo chmod -x /etc/grub.d/10_linux /etc/grub.d/20_memtest86+ /etc/grub.d/30_os-prober

                  + Run "sudo update-grub"
                  + The updated /boot/grub/grub.cfg file should now contain only sections for "00_header", "05_debian_theme" and "40_custom".
                  + The grub.cfg file will not be updated with the addition of a new kernel. To add a new kernel, make "10_linux" executable, run "sudo update-grub" to refresh the available kernels, and repeat these instructions.

            - Incorporating the DEFAULT=save Option: In order to enable the "saved default" option with which Grub 2 preselects the last successfully-used option at boot, the "DEFAULT=save" option must be entered in /etc/default/grub and the 40_custom file must be modified. An example of a 40_custom file follows:

                    #! /bin/sh -e

                    . ${libdir}/grub/grub-mkconfig_lib
                    echo "Adding SystemRescueCD & Custom Kernel" >&2

                    menuentry "Jaunty 2.6.28-15-custom" {
                    save_default_entry | sed -e "s/^/\t/"
                    set root=(hd0,7)
                    linux /boot/vmlinuz-2.6.28-15-custom root=UUID=12c55255-27b3-488b-hje7e-9dbe4e2esfg5 ro quiet splash
                    initrd /boot/initrd.img-2.6.28-15-custom

                    menuentry "SystemRescue" {
                    save_default_entry | sed -e "s/^/\t/"
                    set root=(hd0,6)
                    linux /sysrcd/rescuecd subdir=sysrcd setkmap=us
                    initrd /sysrcd/initram.igz
                  + Manual Windows Entry (with /etc/grub.d/30_os-prober made unexecutable)
                    #! /bin/sh -e

                    echo "Adding Windows 43_custom" >&2
                    menuentry "Windows Vista 43_custom" {
                    insmod ntfs
                    set root=(hd0,1)
                    search --no-floppy --fs-uuid --set CFFCFF9EECFF7F49
                    chainloader +1

      - Don't forget to run "sudo update-grub" after making any changes to your /etc/grub.d files.

      x Manual Editing of grub.cfg (Not encouraged)
        Manual editing of /boot/grub/grub.cfg is not encouraged. Think of grub.cfg as a result, not as an initiator. The files that should be edited are contained in the /etc/grub.d folders and the /etc/default/grub file.

        In order to discourage its editing, grub.cfg is read-only. Even attempting to open, edit and save this file using root privileges cannot be done until the 'read-only' status is changed. If you must edit this file:

        sudo chmod +w /boot/grub/grub.cfg
        gksudo gedit /boot/grub/grub.cfg

        Note: This file is returned to 'read-only' status anytime the update-grub command is run.

---Removing Entries from Grub 2

  Entries should be removed by editing or removing files in the /etc/grub.d folder. The /boot/grub/grub.cfg file is read-only and should not normally require editing.

      x Automatically.

            - Too Many Kernels? Kernels removed via Synaptic or with "apt-get remove" will automatically update grub.cfg and no user action is required.
                  + In Synaptic, type the kernel number in the search window at the upper right (for example - 2.6.28-11).
                  + Find the "linux-image" and "linux-headers" files for the applicable kernel (example - linux-image-2.6.26-11 or "linux-image-2.6.26-11-generic).
                  + Right click and select "Mark for Complete Removal" and then press the Apply main menu button.
                  + The kernels will be removed from your system and from the Grub menu.
                  + If you are not sure of the kernel you are currently using, in a terminal type "uname -r".
                  + Many users keep one previous kernel on the machine which previously ran without problems.

            - Other Operating Systems which have been removed from the computer will also be removed from the menu once "update-grub2" is run as root.

            - To prevent one of the /etc/init.d files from running, remove the "executable" bit.
                  + Example: If you don't want to see the "Memtest86+" entries, run this command:

                    sudo chmod -x /etc/grub.d/20_memtest86+

                  + Run the update-grub command to allow the changes to be incorporated in grub.cfg

        User-Created Entries.

            - To remove a user-created menu entry, remove the applicable file from the /etc/grub.d folder.

            - If a custom file contains multiple entries, individual items may be removed and others retained.

            - Once the file has been removed or edited, run "update-grub2" to update grub.cfg.
  • This is very big help and cleared answer. Really appreciate it.
    – navorser
    Aug 27, 2014 at 12:28
  • No. It is a personal collection. It seems difficult to conform to all. I recommend expanding this answer to say something about how to do that – Eliah Kagan - Terribly hard to read. – guntbert
    – kyodake
    Aug 27, 2014 at 19:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.