6 Writing your own configuration file
*************************************

GRUB is configured using 'grub.cfg', usually located under '/boot/grub'.
This file is quite flexible, but most users will not need to write the
whole thing by hand.

6.1 Simple configuration handling
=================================

The program 'grub-mkconfig' (*note Invoking grub-mkconfig::) generates
'grub.cfg' files suitable for most cases.  It is suitable for use when
upgrading a distribution, and will discover available kernels and
attempt to generate menu entries for them.

   'grub-mkconfig' does have some limitations.  While adding extra
custom menu entries to the end of the list can be done by editing
'/etc/grub.d/40_custom' or creating '/boot/grub/custom.cfg', changing
the order of menu entries or changing their titles may require making
complex changes to shell scripts stored in '/etc/grub.d/'.  This may be
improved in the future.  In the meantime, those who feel that it would
be easier to write 'grub.cfg' directly are encouraged to do so (*note
Booting::, and *note Shell-like scripting::), and to disable any system
provided by their distribution to automatically run 'grub-mkconfig'.

   The file '/etc/default/grub' controls the operation of
'grub-mkconfig'.  It is sourced by a shell script, and so must be valid
POSIX shell input; normally, it will just be a sequence of 'KEY=value'
lines, but if the value contains spaces or other special characters then
it must be quoted.  For example:

     GRUB_TERMINAL_INPUT="console serial"

   Valid keys in '/etc/default/grub' are as follows:

'GRUB_DEFAULT'
     The default menu entry.  This may be a number, in which case it
     identifies the Nth entry in the generated menu counted from zero,
     or the title of a menu entry, or the special string 'saved'.  Using
     the id may be useful if you want to set a menu entry as the default
     even though there may be a variable number of entries before it.

     For example, if you have:

     menuentry 'Example GNU/Linux distribution' --class gnu-linux --id example-gnu-linux {
     	...
     }

     then you can make this the default using:

          GRUB_DEFAULT=example-gnu-linux

     Previously it was documented the way to use entry title.  While
     this still works it's not recommended since titles often contain
     unstable device names and may be translated

     If you set this to 'saved', then the default menu entry will be
     that saved by 'GRUB_SAVEDEFAULT' or 'grub-set-default'.  This
     relies on the environment block, which may not be available in all
     situations (*note Environment block::).

     The default is '0'.

'GRUB_SAVEDEFAULT'
     If this option is set to 'true', then, when an entry is selected,
     save it as a new default entry for use by future runs of GRUB. This
     is only useful if 'GRUB_DEFAULT=saved'; it is a separate option
     because 'GRUB_DEFAULT=saved' is useful without this option, in
     conjunction with 'grub-set-default'.  Unset by default.  This
     option relies on the environment block, which may not be available
     in all situations (*note Environment block::).

'GRUB_TIMEOUT'
     Boot the default entry this many seconds after the menu is
     displayed, unless a key is pressed.  The default is '5'.  Set to
     '0' to boot immediately without displaying the menu, or to '-1' to
     wait indefinitely.

     If 'GRUB_TIMEOUT_STYLE' is set to 'countdown' or 'hidden', the
     timeout is instead counted before the menu is displayed.

'GRUB_TIMEOUT_STYLE'
     If this option is unset or set to 'menu', then GRUB will display
     the menu and then wait for the timeout set by 'GRUB_TIMEOUT' to
     expire before booting the default entry.  Pressing a key interrupts
     the timeout.

     If this option is set to 'countdown' or 'hidden', then, before
     displaying the menu, GRUB will wait for the timeout set by
     'GRUB_TIMEOUT' to expire.  If <ESC> is pressed during that time, it
     will display the menu and wait for input.  If a hotkey associated
     with a menu entry is pressed, it will boot the associated menu
     entry immediately.  If the timeout expires before either of these
     happens, it will boot the default entry.  In the 'countdown' case,
     it will show a one-line indication of the remaining time.

'GRUB_DEFAULT_BUTTON'
'GRUB_TIMEOUT_BUTTON'
'GRUB_TIMEOUT_STYLE_BUTTON'
'GRUB_BUTTON_CMOS_ADDRESS'
     Variants of the corresponding variables without the '_BUTTON'
     suffix, used to support vendor-specific power buttons.  *Note
     Vendor power-on keys::.

'GRUB_DISTRIBUTOR'
     Set by distributors of GRUB to their identifying name.  This is
     used to generate more informative menu entry titles.

'GRUB_TERMINAL_INPUT'
     Select the terminal input device.  You may select multiple devices
     here, separated by spaces.

     Valid terminal input names depend on the platform, but may include
     'console' (native platform console), 'serial' (serial terminal),
     'serial_<port>' (serial terminal with explicit port selection),
     'at_keyboard' (PC AT keyboard), or 'usb_keyboard' (USB keyboard
     using the HID Boot Protocol, for cases where the firmware does not
     handle this).

     The default is to use the platform's native terminal input.

'GRUB_TERMINAL_OUTPUT'
     Select the terminal output device.  You may select multiple devices
     here, separated by spaces.

     Valid terminal output names depend on the platform, but may include
     'console' (native platform console), 'serial' (serial terminal),
     'serial_<port>' (serial terminal with explicit port selection),
     'gfxterm' (graphics-mode output), 'vga_text' (VGA text output),
     'mda_text' (MDA text output), 'morse' (Morse-coding using system
     beeper) or 'spkmodem' (simple data protocol using system speaker).

     'spkmodem' is useful when no serial port is available.  Connect the
     output of sending system (where GRUB is running) to line-in of
     receiving system (usually developer machine).  On receiving system
     compile 'spkmodem-recv' from 'util/spkmodem-recv.c' and run:

          parecord --channels=1 --rate=48000 --format=s16le | ./spkmodem-recv

     The default is to use the platform's native terminal output.

'GRUB_TERMINAL'
     If this option is set, it overrides both 'GRUB_TERMINAL_INPUT' and
     'GRUB_TERMINAL_OUTPUT' to the same value.

'GRUB_SERIAL_COMMAND'
     A command to configure the serial port when using the serial
     console.  *Note serial::.  Defaults to 'serial'.

'GRUB_CMDLINE_LINUX'
     Command-line arguments to add to menu entries for the Linux kernel.

'GRUB_CMDLINE_LINUX_DEFAULT'
     Unless 'GRUB_DISABLE_RECOVERY' is set to 'true', two menu entries
     will be generated for each Linux kernel: one default entry and one
     entry for recovery mode.  This option lists command-line arguments
     to add only to the default menu entry, after those listed in
     'GRUB_CMDLINE_LINUX'.

'GRUB_CMDLINE_NETBSD'
'GRUB_CMDLINE_NETBSD_DEFAULT'
     As 'GRUB_CMDLINE_LINUX' and 'GRUB_CMDLINE_LINUX_DEFAULT', but for
     NetBSD.

'GRUB_CMDLINE_GNUMACH'
     As 'GRUB_CMDLINE_LINUX', but for GNU Mach.

'GRUB_CMDLINE_XEN'
'GRUB_CMDLINE_XEN_DEFAULT'
     The values of these options are passed to Xen hypervisor Xen menu
     entries, for all respectively normal entries.

'GRUB_CMDLINE_LINUX_XEN_REPLACE'
'GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT'
     The values of these options replace the values of
     'GRUB_CMDLINE_LINUX' and 'GRUB_CMDLINE_LINUX_DEFAULT' for Linux and
     Xen menu entries.

'GRUB_EARLY_INITRD_LINUX_CUSTOM'
'GRUB_EARLY_INITRD_LINUX_STOCK'
     List of space-separated early initrd images to be loaded from
     '/boot'.  This is for loading things like CPU microcode, firmware,
     ACPI tables, crypto keys, and so on.  These early images will be
     loaded in the order declared, and all will be loaded before the
     actual functional initrd image.

     'GRUB_EARLY_INITRD_LINUX_STOCK' is for your distribution to declare
     images that are provided by the distribution.  It should not be
     modified without understanding the consequences.  They will be
     loaded first.

     'GRUB_EARLY_INITRD_LINUX_CUSTOM' is for your custom created images.

     The default stock images are as follows, though they may be
     overridden by your distribution:
          intel-uc.img intel-ucode.img amd-uc.img amd-ucode.img early_ucode.cpio microcode.cpio

'GRUB_DISABLE_LINUX_UUID'
     Normally, 'grub-mkconfig' will generate menu entries that use
     universally-unique identifiers (UUIDs) to identify the root
     filesystem to the Linux kernel, using a 'root=UUID=...' kernel
     parameter.  This is usually more reliable, but in some cases it may
     not be appropriate.  To disable the use of UUIDs, set this option
     to 'true'.

'GRUB_DISABLE_LINUX_PARTUUID'
     If 'grub-mkconfig' cannot identify the root filesystem via its
     universally-unique indentifier (UUID), 'grub-mkconfig' can use the
     UUID of the partition containing the filesystem to identify the
     root filesystem to the Linux kernel via a 'root=PARTUUID=...'
     kernel parameter.  This is not as reliable as using the filesystem
     UUID, but is more reliable than using the Linux device names.  When
     'GRUB_DISABLE_LINUX_PARTUUID' is set to 'false', the Linux kernel
     version must be 2.6.37 (3.10 for systems using the MSDOS partition
     scheme) or newer.  This option defaults to 'true'.  To enable the
     use of partition UUIDs, set this option to 'false'.

'GRUB_DISABLE_RECOVERY'
     If this option is set to 'true', disable the generation of recovery
     mode menu entries.

'GRUB_VIDEO_BACKEND'
     If graphical video support is required, either because the
     'gfxterm' graphical terminal is in use or because
     'GRUB_GFXPAYLOAD_LINUX' is set, then 'grub-mkconfig' will normally
     load all available GRUB video drivers and use the one most
     appropriate for your hardware.  If you need to override this for
     some reason, then you can set this option.

     After 'grub-install' has been run, the available video drivers are
     listed in '/boot/grub/video.lst'.

'GRUB_GFXMODE'
     Set the resolution used on the 'gfxterm' graphical terminal.  Note
     that you can only use modes which your graphics card supports via
     VESA BIOS Extensions (VBE), so for example native LCD panel
     resolutions may not be available.  The default is 'auto', which
     tries to select a preferred resolution.  *Note gfxmode::.

'GRUB_BACKGROUND'
     Set a background image for use with the 'gfxterm' graphical
     terminal.  The value of this option must be a file readable by GRUB
     at boot time, and it must end with '.png', '.tga', '.jpg', or
     '.jpeg'.  The image will be scaled if necessary to fit the screen.

'GRUB_THEME'
     Set a theme for use with the 'gfxterm' graphical terminal.

'GRUB_GFXPAYLOAD_LINUX'
     Set to 'text' to force the Linux kernel to boot in normal text
     mode, 'keep' to preserve the graphics mode set using
     'GRUB_GFXMODE', 'WIDTHxHEIGHT'['xDEPTH'] to set a particular
     graphics mode, or a sequence of these separated by commas or
     semicolons to try several modes in sequence.  *Note gfxpayload::.

     Depending on your kernel, your distribution, your graphics card,
     and the phase of the moon, note that using this option may cause
     GNU/Linux to suffer from various display problems, particularly
     during the early part of the boot sequence.  If you have problems,
     set this option to 'text' and GRUB will tell Linux to boot in
     normal text mode.

'GRUB_DISABLE_OS_PROBER'
     Normally, 'grub-mkconfig' will try to use the external 'os-prober'
     program, if installed, to discover other operating systems
     installed on the same system and generate appropriate menu entries
     for them.  Set this option to 'true' to disable this.

'GRUB_OS_PROBER_SKIP_LIST'
     List of space-separated FS UUIDs of filesystems to be ignored from
     os-prober output.  For efi chainloaders it's <UUID>@<EFI FILE>

'GRUB_DISABLE_SUBMENU'
     Normally, 'grub-mkconfig' will generate top level menu entry for
     the kernel with highest version number and put all other found
     kernels or alternative menu entries for recovery mode in submenu.
     For entries returned by 'os-prober' first entry will be put on top
     level and all others in submenu.  If this option is set to 'y',
     flat menu with all entries on top level will be generated instead.
     Changing this option will require changing existing values of
     'GRUB_DEFAULT', 'fallback' (*note fallback::) and 'default' (*note
     default::) environment variables as well as saved default entry
     using 'grub-set-default' and value used with 'grub-reboot'.

'GRUB_ENABLE_CRYPTODISK'
     If set to 'y', 'grub-mkconfig' and 'grub-install' will check for
     encrypted disks and generate additional commands needed to access
     them during boot.  Note that in this case unattended boot is not
     possible because GRUB will wait for passphrase to unlock encrypted
     container.

'GRUB_INIT_TUNE'
     Play a tune on the speaker when GRUB starts.  This is particularly
     useful for users unable to see the screen.  The value of this
     option is passed directly to *note play::.

'GRUB_BADRAM'
     If this option is set, GRUB will issue a *note badram:: command to
     filter out specified regions of RAM.

'GRUB_PRELOAD_MODULES'
     This option may be set to a list of GRUB module names separated by
     spaces.  Each module will be loaded as early as possible, at the
     start of 'grub.cfg'.

   The following options are still accepted for compatibility with
existing configurations, but have better replacements:

'GRUB_HIDDEN_TIMEOUT'
     Wait this many seconds before displaying the menu.  If <ESC> is
     pressed during that time, display the menu and wait for input
     according to 'GRUB_TIMEOUT'.  If a hotkey associated with a menu
     entry is pressed, boot the associated menu entry immediately.  If
     the timeout expires before either of these happens, display the
     menu for the number of seconds specified in 'GRUB_TIMEOUT' before
     booting the default entry.

     If you set 'GRUB_HIDDEN_TIMEOUT', you should also set
     'GRUB_TIMEOUT=0' so that the menu is not displayed at all unless
     <ESC> is pressed.

     This option is unset by default, and is deprecated in favour of the
     less confusing 'GRUB_TIMEOUT_STYLE=countdown' or
     'GRUB_TIMEOUT_STYLE=hidden'.

'GRUB_HIDDEN_TIMEOUT_QUIET'
     In conjunction with 'GRUB_HIDDEN_TIMEOUT', set this to 'true' to
     suppress the verbose countdown while waiting for a key to be
     pressed before displaying the menu.

     This option is unset by default, and is deprecated in favour of the
     less confusing 'GRUB_TIMEOUT_STYLE=countdown'.

'GRUB_HIDDEN_TIMEOUT_BUTTON'
     Variant of 'GRUB_HIDDEN_TIMEOUT', used to support vendor-specific
     power buttons.  *Note Vendor power-on keys::.

     This option is unset by default, and is deprecated in favour of the
     less confusing 'GRUB_TIMEOUT_STYLE=countdown' or
     'GRUB_TIMEOUT_STYLE=hidden'.

   For more detailed customisation of 'grub-mkconfig''s output, you may
edit the scripts in '/etc/grub.d' directly.  '/etc/grub.d/40_custom' is
particularly useful for adding entire custom menu entries; simply type
the menu entries you want to add at the end of that file, making sure to
leave at least the first two lines intact.

6.2 Root Identifcation Heuristics
=================================

If the target operating system uses the Linux kernel, 'grub-mkconfig'
attempts to identify the root file system via a heuristic algoirthm.
This algorithm selects the identification method of the root file system
by considering three factors.  The first is if an initrd for the target
operating system is also present.  The second is
'GRUB_DISABLE_LINUX_UUID' and if set to 'true', prevents 'grub-mkconfig'
from identifying the root file system by its UUID. The third is
'GRUB_DISABLE_LINUX_PARTUUID' and if set to 'true', prevents
'grub-mkconfig' from identifying the root file system via the UUID of
its enclosing partition.  If the variables are assigned any other value,
that value is considered equivalent to 'false'.  The variables are also
considered to be set to 'false' if they are not set.

   When booting, the Linux kernel will delegate the task of mounting the
root filesystem to the initrd.  Most initrd images determine the root
file system by checking the Linux kernel's command-line for the 'root'
key and use its value as the identification method of the root file
system.  To improve the reliability of booting, most initrd images also
allow the root file system to be identified by its UUID. Because of this
behavior, the 'grub-mkconfig' command will set 'root' to 'root=UUID=...'
to provide the initrd with the filesystem UUID of the root file system.

   If no initrd is detected or 'GRUB_DISABLE_LINUX_UUID' is set to
'true' then 'grub-command' will identify the root filesystem by setting
the kernel command-line variable 'root' to 'root=PARTUUID=...' unless
'GRUB_DISABLE_LINUX_PARTUUID' is also set to 'true'.  If
'GRUB_DISABLE_LINUX_PARTUUID' is also set to 'true', 'grub-command' will
identify by its Linux device name.

   The following table summarizes the behavior of the 'grub-mkconfig'
command.

Initrd     GRUB_DISABLE_LINUX_PARTUUID   GRUB_DISABLE_LINUX_UUID   Linux Root
detected   Set To                        Set To                    ID Method
--------------------------------------------------------------------------------
false      false                         false                     part UUID
false      false                         true                      part UUID
false      true                          false                     dev name
false      true                          true                      dev name
true       false                         false                     fs UUID
true       false                         true                      part UUID
true       true                          false                     fs UUID
true       true                          true                      dev name

   Remember, 'GRUB_DISABLE_LINUX_PARTUUID' and 'GRUB_DISABLE_LINUX_UUID'
are also considered to be set to 'false' when they are unset.

6.3 Writing full configuration files directly
=============================================

'grub.cfg' is written in GRUB's built-in scripting language, which has a
syntax quite similar to that of GNU Bash and other Bourne shell
derivatives.

Words
=====

A "word" is a sequence of characters considered as a single unit by
GRUB. Words are separated by "metacharacters", which are the following
plus space, tab, and newline:

     { } | & $ ; < >

   Quoting may be used to include metacharacters in words; see below.

Reserved words
==============

Reserved words have a special meaning to GRUB. The following words are
recognised as reserved when unquoted and either the first word of a
simple command or the third word of a 'for' command:

     ! [[ ]] { }
     case do done elif else esac fi for function
     if in menuentry select then time until while

   Not all of these reserved words have a useful purpose yet; some are
reserved for future expansion.

Quoting
=======

Quoting is used to remove the special meaning of certain characters or
words.  It can be used to treat metacharacters as part of a word, to
prevent reserved words from being recognised as such, and to prevent
variable expansion.

   There are three quoting mechanisms: the escape character, single
quotes, and double quotes.

   A non-quoted backslash (\) is the "escape character".  It preserves
the literal value of the next character that follows, with the exception
of newline.

   Enclosing characters in single quotes preserves the literal value of
each character within the quotes.  A single quote may not occur between
single quotes, even when preceded by a backslash.

   Enclosing characters in double quotes preserves the literal value of
all characters within the quotes, with the exception of '$' and '\'.
The '$' character retains its special meaning within double quotes.  The
backslash retains its special meaning only when followed by one of the
following characters: '$', '"', '\', or newline.  A backslash-newline
pair is treated as a line continuation (that is, it is removed from the
input stream and effectively ignored(1) (*note Shell-like
scripting-Footnote-1::)).  A double quote may be quoted within double
quotes by preceding it with a backslash.

Variable expansion
==================

The '$' character introduces variable expansion.  The variable name to
be expanded may be enclosed in braces, which are optional but serve to
protect the variable to be expanded from characters immediately
following it which could be interpreted as part of the name.

   Normal variable names begin with an alphabetic character, followed by
zero or more alphanumeric characters.  These names refer to entries in
the GRUB environment (*note Environment::).

   Positional variable names consist of one or more digits.  They
represent parameters passed to function calls, with '$1' representing
the first parameter, and so on.

   The special variable name '?' expands to the exit status of the most
recently executed command.  When positional variable names are active,
other special variable names '@', '*' and '#' are defined and they
expand to all positional parameters with necessary quoting, positional
parameters without any quoting, and positional parameter count
respectively.

Comments
========

A word beginning with '#' causes that word and all remaining characters
on that line to be ignored.

Simple commands
===============

A "simple command" is a sequence of words separated by spaces or tabs
and terminated by a semicolon or a newline.  The first word specifies
the command to be executed.  The remaining words are passed as arguments
to the invoked command.

   The return value of a simple command is its exit status.  If the
reserved word '!' precedes the command, then the return value is instead
the logical negation of the command's exit status.

Compound commands
=================

A "compound command" is one of the following:

for NAME in WORD ...; do LIST; done
     The list of words following 'in' is expanded, generating a list of
     items.  The variable NAME is set to each element of this list in
     turn, and LIST is executed each time.  The return value is the exit
     status of the last command that executes.  If the expansion of the
     items following 'in' results in an empty list, no commands are
     executed, and the return status is 0.

if LIST; then LIST; [elif LIST; then LIST;] ... [else LIST;] fi
     The 'if' LIST is executed.  If its exit status is zero, the 'then'
     LIST is executed.  Otherwise, each 'elif' LIST is executed in turn,
     and if its exit status is zero, the corresponding 'then' LIST is
     executed and the command completes.  Otherwise, the 'else' LIST is
     executed, if present.  The exit status is the exit status of the
     last command executed, or zero if no condition tested true.

while COND; do LIST; done
until COND; do LIST; done
     The 'while' command continuously executes the 'do' LIST as long as
     the last command in COND returns an exit status of zero.  The
     'until' command is identical to the 'while' command, except that
     the test is negated; the 'do' LIST is executed as long as the last
     command in COND returns a non-zero exit status.  The exit status of
     the 'while' and 'until' commands is the exit status of the last
     'do' LIST command executed, or zero if none was executed.

function NAME { COMMAND; ... }
     This defines a function named NAME.  The "body" of the function is
     the list of commands within braces, each of which must be
     terminated with a semicolon or a newline.  This list of commands
     will be executed whenever NAME is specified as the name of a simple
     command.  Function definitions do not affect the exit status in
     '$?'.  When executed, the exit status of a function is the exit
     status of the last command executed in the body.

menuentry TITLE ['--class=class' ...] ['--users=users'] ['--unrestricted'] ['--hotkey=key'] ['--id=id'] { COMMAND; ... }
     *Note menuentry::.

Built-in Commands
=================

Some built-in commands are also provided by GRUB script to help script
writers perform actions that are otherwise not possible.  For example,
these include commands to jump out of a loop without fully completing
it, etc.

break ['n']
     Exit from within a 'for', 'while', or 'until' loop.  If 'n' is
     specified, break 'n' levels.  'n' must be greater than or equal to
     1.  If 'n' is greater than the number of enclosing loops, all
     enclosing loops are exited.  The return value is 0 unless 'n' is
     not greater than or equal to 1.

continue ['n']
     Resume the next iteration of the enclosing 'for', 'while' or
     'until' loop.  If 'n' is specified, resume at the 'n'th enclosing
     loop.  'n' must be greater than or equal to 1.  If 'n' is greater
     than the number of enclosing loops, the last enclosing loop (the
     "top-level" loop) is resumed.  The return value is 0 unless 'n' is
     not greater than or equal to 1.

return ['n']
     Causes a function to exit with the return value specified by 'n'.
     If 'n' is omitted, the return status is that of the last command
     executed in the function body.  If used outside a function the
     return status is false.

setparams ['arg'] ...
     Replace positional parameters starting with '$1' with arguments to
     'setparams'.

shift ['n']
     The positional parameters from 'n'+1 ... are renamed to '$1'....
     Parameters represented by the numbers '$#' down to '$#'-'n'+1 are
     unset.  'n' must be a non-negative number less than or equal to
     '$#'.  If 'n' is 0, no parameters are changed.  If 'n' is not
     given, it is assumed to be 1.  If 'n' is greater than '$#', the
     positional parameters are not changed.  The return status is
     greater than zero if 'n' is greater than '$#' or less than zero;
     otherwise 0.

   (1) Currently a backslash-newline pair within a variable name is not
handled properly, so use this feature with some care.

6.4 Multi-boot manual config
============================

Currently autogenerating config files for multi-boot environments
depends on os-prober and has several shortcomings.  While fixing it is
scheduled for the next release, meanwhile you can make use of the power
of GRUB syntax and do it yourself.  A possible configuration is detailed
here, feel free to adjust to your needs.

   First create a separate GRUB partition, big enough to hold GRUB. Some
of the following entries show how to load OS installer images from this
same partition, for that you obviously need to make the partition large
enough to hold those images as well.  Mount this partition on/mnt/boot
and disable GRUB in all OSes and manually install self-compiled latest
GRUB with:

   'grub-install --boot-directory=/mnt/boot /dev/sda'

   In all the OSes install GRUB tools but disable installing GRUB in
bootsector, so you'll have menu.lst and grub.cfg available for use.
Also disable os-prober use by setting:

   'GRUB_DISABLE_OS_PROBER=true'

   in /etc/default/grub

   Then write a grub.cfg (/mnt/boot/grub/grub.cfg):


     menuentry "OS using grub2" {
        insmod xfs
        search --set=root --label OS1 --hint hd0,msdos8
        configfile /boot/grub/grub.cfg
     }

     menuentry "OS using grub2-legacy" {
        insmod ext2
        search --set=root --label OS2 --hint hd0,msdos6
        legacy_configfile /boot/grub/menu.lst
     }

     menuentry "Windows XP" {
        insmod ntfs
        search --set=root --label WINDOWS_XP --hint hd0,msdos1
        ntldr /ntldr
     }

     menuentry "Windows 7" {
        insmod ntfs
        search --set=root --label WINDOWS_7 --hint hd0,msdos2
        ntldr /bootmgr
     }

     menuentry "FreeBSD" {
               insmod zfs
               search --set=root --label freepool --hint hd0,msdos7
               kfreebsd /freebsd@/boot/kernel/kernel
               kfreebsd_module_elf /freebsd@/boot/kernel/opensolaris.ko
               kfreebsd_module_elf /freebsd@/boot/kernel/zfs.ko
               kfreebsd_module /freebsd@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache
               set kFreeBSD.vfs.root.mountfrom=zfs:freepool/freebsd
               set kFreeBSD.hw.psm.synaptics_support=1
     }

     menuentry "experimental GRUB" {
               search --set=root --label GRUB --hint hd0,msdos5
               multiboot /experimental/grub/i386-pc/core.img
     }

     menuentry "Fedora 16 installer" {
               search --set=root --label GRUB --hint hd0,msdos5
               linux /fedora/vmlinuz lang=en_US keymap=sg resolution=1280x800
               initrd /fedora/initrd.img
     }

     menuentry "Fedora rawhide installer" {
               search --set=root --label GRUB --hint hd0,msdos5
               linux /fedora/vmlinuz repo=ftp://mirror.switch.ch/mirror/fedora/linux/development/rawhide/x86_64 lang=en_US keymap=sg resolution=1280x800
               initrd /fedora/initrd.img
     }

     menuentry "Debian sid installer" {
               search --set=root --label GRUB --hint hd0,msdos5
               linux /debian/dists/sid/main/installer-amd64/current/images/hd-media/vmlinuz
               initrd /debian/dists/sid/main/installer-amd64/current/images/hd-media/initrd.gz
     }


   Notes:
   * Argument to search after -label is FS LABEL. You can also use UUIDs
     with -fs-uuid UUID instead of -label LABEL. You could also use
     direct 'root=hd0,msdosX' but this is not recommended due to device
     name instability.

6.5 Embedding a configuration file into GRUB
============================================

GRUB supports embedding a configuration file directly into the core
image, so that it is loaded before entering normal mode.  This is
useful, for example, when it is not straightforward to find the real
configuration file, or when you need to debug problems with loading that
file.  'grub-install' uses this feature when it is not using BIOS disk
functions or when installing to a different disk from the one containing
'/boot/grub', in which case it needs to use the 'search' command (*note
search::) to find '/boot/grub'.

   To embed a configuration file, use the '-c' option to 'grub-mkimage'.
The file is copied into the core image, so it may reside anywhere on the
file system, and may be removed after running 'grub-mkimage'.

   After the embedded configuration file (if any) is executed, GRUB will
load the 'normal' module (*note normal::), which will then read the real
configuration file from '$prefix/grub.cfg'.  By this point, the 'root'
variable will also have been set to the root device name.  For example,
'prefix' might be set to '(hd0,1)/boot/grub', and 'root' might be set to
'hd0,1'.  Thus, in most cases, the embedded configuration file only
needs to set the 'prefix' and 'root' variables, and then drop through to
GRUB's normal processing.  A typical example of this might look like
this:

     search.fs_uuid 01234567-89ab-cdef-0123-456789abcdef root
     set prefix=($root)/boot/grub

   (The 'search_fs_uuid' module must be included in the core image for
this example to work.)

   In more complex cases, it may be useful to read other configuration
files directly from the embedded configuration file.  This allows such
things as reading files not called 'grub.cfg', or reading files from a
directory other than that where GRUB's loadable modules are installed.
To do this, include the 'configfile' and 'normal' modules in the core
image, and embed a configuration file that uses the 'configfile' command
to load another file.  The following example of this also requires the
'echo', 'search_label', and 'test' modules to be included in the core
image:

     search.fs_label grub root
     if [ -e /boot/grub/example/test1.cfg ]; then
         set prefix=($root)/boot/grub
         configfile /boot/grub/example/test1.cfg
     else
         if [ -e /boot/grub/example/test2.cfg ]; then
             set prefix=($root)/boot/grub
             configfile /boot/grub/example/test2.cfg
         else
             echo "Could not find an example configuration file!"
         fi
     fi

   The embedded configuration file may not contain menu entries
directly, but may only read them from elsewhere using 'configfile'.

