Sunday, 21 January 2018

Linux: GRUB

GRUB, or the GRand Unified Boot loader, was for a long time one of the most common Linux boot loaders. You can install GRUB into the MBR of your bootable hard drive or into the partition boot record of a partition. You can also install it on removable devices such as floppy disks, CDs, or USB keys. It is a good idea to practice on a floppy disk or USB key if you are not already familiar with GRUB. The examples in this tutorial show you how.

Note: Most GRUB examples in this tutorial use CentOS 6.

During Linux installation, you often specify your choice of boot manager. If you choose LILO, then you might not have GRUB installed. If you do not have GRUB installed and it is available for your distribution, then you need to install the package for it. This tutorial assumes that you already have the GRUB package installed.

GRUB (Legacy) has a configuration file that is usually stored in /boot/grub/grub.conf. If your file system supports symbolic links, as most Linux file systems do, you probably have /boot/grub/menu.lst as a symbolic link to /boot/grub/grub.conf.

The grub command (/sbin/grub, or, on some systems, /usr/sbin/grub) is a small but reasonably powerful shell that supports several commands for installing GRUB, booting systems, locating and displaying configuration files, and similar tasks. This shell shares much code with the second stage GRUB boot loader, so it is useful to learn about GRUB without having to boot to a second stage GRUB environment. The GRUB stage 2 runs either in menu mode, so that you can choose an operating system from a menu, or in command mode, where you specify individual commands to load a system. There are also several other commands, such as grub-install, that use the grub shell and help automate tasks such as installing GRUB.

Listing 1 shows a fairly complex GRUB configuration file. As you look through it, remember one important thing: GRUB, at least GRUB Legacy, counts drives, partitions, and things that need to be counted, starting at 0 rather than 1. The second entry for CentOS has a kernel line that is very long. Listing 1 shows it with a backslash (\) indicating where it was broken for publication.

Listing 1. /boot/grub/menu.lst GRUB configuration example

# grub.conf generated by anaconda
#
# You do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,5)
#          kernel /boot/vmlinuz-version ro root=/dev/hda6
#          initrd /boot/initrd-version.img
#boot=/dev/hda
default=0
timeout=60
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
#password --md5 $1$y.uQRs1W$Sqs30hDB3GtE957PoiDWO.

title Fedora 22 64-bit (sda5)
    root (hd0,4)
        kernel /boot/grub2/i386-pc/core.img

title Fedora 18 64-bit (sda7)
    root (hd0,6)
        kernel /boot/grub2/i386-pc/core.img

title CentOS 6 64-bit (sda11)
        root (hd0,10)
        configfile /boot/grub/menu.lst

title CentOS (2.6.32-504.23.4.el6.x86_64)
    root (hd0,10)
    kernel /boot/vmlinuz-2.6.32-504.23.4.el6.x86_64 ro \
           root=UUID=2f60a3b4-ef6c-4d4c-9ef4-50d7f75124a2 rd_NO_LUKS rd_NO_LVM \
           LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=128M \
           KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
    initrd /boot/initramfs-2.6.32-504.23.4.el6.x86_64.img

title Fedora 20 64-bit (sda10)
    root (hd0,9)
        configfile /boot/grub/menu.lst

title Ubuntu 12.04-LTS 64-bit (sda9)
    root (hd0,8)
        kernel /boot/grub/core.img

title Ubuntu 14.04 32-bit (sda12)
    root (hd0,11)
        kernel /boot/grub/core.img

title Slackware 13.37 64-bit (sda6)
    root (hd0,5)
        chainloader +1
        boot
   
title Open SUSE 11.4 64-bit (sda8)
    root (hd0,7)
        configfile /boot/grub/menu.lst

title Windows Example
    rootnoverify (hd0,0)
    chainloader +1
#####

The first set of options in Listing 1 control how GRUB operates. For GRUB, these are called menu commands, and they must appear before other commands. The remaining sections give per-image options for the operating systems that you want to allow GRUB to boot. "Title" is considered a menu command. Each instance of title is followed by one or more general or menu entry commands.

The menu commands that apply to all other sections in Listing 1 are:

#

Any line starting with a # is a comment and is ignored by GRUB. This particular configuration file was originally generated by anaconda, the Red Hat installer. You will probably find comments added to your GRUB configuration file if you install GRUB when you install Linux. The comments often serve as an aid to the system upgrade program so that you can keep your GRUB configuration current with upgraded kernels. Pay attention to any markers that are left for this purpose if you edit the configuration yourself.

default
Specifies which system to load if the user does not make a choice within a timeout. In Listing 1, default=0 means to load the first entry. Remember that GRUB counts from 0 rather than 1. If not specified, then the default is to boot the first entry, entry number 0.

timeout
Specifies a timeout in seconds before booting the default entry. Note that LILO uses tenths of a second for timeouts, while GRUB uses whole seconds.

splashimage
Specifies the background, or splash, image to be displayed with the boot menu. GRUB Legacy refers to the first hard drive as (hd0) and the first partition on that drive as (hd0,0), so the specification of splashimage=(hd0,0)/boot/grub/splash.xpm.gz means to use the file /boot/grub/splash.xpm.gz located on partition 1 of the first hard drive. Remember to count from 0. The image is an XPM file compressed with gzip. Support for splashimage is a patch that might or might not be included in your distribution.

password
Specifies a password that you must enter before you can unlock the menu and either edit a configuration line or enter GRUB commands. The password can be in clear text. GRUB also permits passwords to be stored as an MD5 digest, as in the commented out example in Listing 1. This is somewhat more secure, and most administrators set a password. Without a password, you have complete access to the GRUB command line.
Listing 1 shows a CentOS kernel, /boot/vmlinuz-2.6.32-504.23.4.el6.x86_64, on /dev/sda11 (hd0,10), plus several systems that are configured to chain load. Listing 1 also has examples of loading GRUB 2 via /boot/grub2/i386-pc/core.img and an example of a typical Windows XP chain loading entry, although this system does not actually have Windows installed. The commands used in these sections are:

title
Is a descriptive title that is shown as the menu item when Grub boots. You use the arrow keys to move up and down through the title list and then press Enter to select a particular entry.

root
Specifies the partition that will be booted. As with splashimage, remember that counting starts at 0, so the first Red Hat system that is specified as root (hd0,6) is actually on partition 7 of the first hard drive (/dev/hda7 in this case), while the first Ubuntu system, which is specified as root (hd1,10), is on the second hard drive (/dev/hdb11). GRUB attempts to mount this partition to check it and provide values to the booted operating system in some cases.

kernel
Specifies the kernel image to be loaded and any required kernel parameters. A kernel value like /boot/grub2/i386-pc/core.img usually means loading a GRUB 2 boot loader from the named root partition.

initrd
Is the name of the initial RAM disk, which contains modules needed by the kernel before your file systems are mounted.

savedefault
Is not used in this example. If the menu command default=saved is specified and the savedefault command is specified for an operating system, then booting that operating system causes it to become the default until another operating system with savedefault specified is booted. In Listing 1, the specification of default=0 overrides any saved default.

boot
Is an optional parameter that instructs GRUB to boot the selected operating system. This is the default action when all commands for a selection have been processed.

lock
Is not used in Listing 1. This does not boot the specified entry until a password is entered. If you use this, then you should also specify a password in the initial options; otherwise, a user can edit out your lock option and boot the system or add "single" to one of the other entries. It is possible to specify a different password for individual entries if you want.

rootnoverify
Is similar to root, except that GRUB does not attempt to mount the file system or verify its parameters. This is usually used for file systems such as NTFS that are not supported by GRUB. You might also use this if you want GRUB to load the master boot record on a hard drive (for example, to access a different configuration file or to reload your previous boot loader).

chainloader
Specifies that another file will be loaded as a stage 1 file. The value "+1" is equivalent to 0+1, which means to load one sector starting at sector 0; that is, load the first sector from the device specified by root or rootnoverify.

configfile
Specifies that the running copy of GRUB replaces its configuration file with one loaded from the target location. For this to work, it is advisable that the version of GRUB that is loading the new configfile is as current as the version that built it.

You now have some idea of what you might find in a typical /boot/grub/grub.conf (or /boot/grub/menu.lst) file. There are many other GRUB commands to provide extensive control over the boot process as well as help with installing GRUB and other tasks. You can learn more about these in the GRUB manual, which should be available on your system through the command info grub.

Before you learn how to deal with such a large GRUB configuration file, let's drop back to a smaller and simpler example. I use the file that CentOS 6 built for me when I installed it on /dev/sda11. This is shown in Listing 2. Again, we have used a backslash (\) to show where we broke long kernel lines for publication.

Listing 2. Basic GRUB configuration built by CentOS 6

# grub.conf generated by anaconda
#
# You do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,10)
#          kernel /boot/vmlinuz-version ro root=/dev/sdd11
#          initrd /boot/initrd-[generic-]version.img
#boot=/dev/sdd11
default=0
timeout=5
splashimage=(hd0,10)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-504.23.4.el6.x86_64)
    root (hd0,10)
    kernel /boot/vmlinuz-2.6.32-504.23.4.el6.x86_64 ro \
           root=UUID=2f60a3b4-ef6c-4d4c-9ef4-50d7f75124a2 rd_NO_LUKS rd_NO_LVM \
           LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=128M \
           KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
    initrd /boot/initramfs-2.6.32-504.23.4.el6.x86_64.img
title CentOS 6 (2.6.32-504.el6.x86_64)
    root (hd0,10)
    kernel /boot/vmlinuz-2.6.32-504.el6.x86_64 ro \
           root=UUID=2f60a3b4-ef6c-4d4c-9ef4-50d7f75124a2 rd_NO_LUKS rd_NO_LVM \
           LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=128M \
           KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
    initrd /boot/initramfs-2.6.32-504.el6.x86_64.img
title Other
    rootnoverify (hd0,0)
    chainloader +1

Notice the command hiddenmenu that you did not see earlier. This causes GRUB to not display a menu, but rather boot the default entry as soon as the timeout expires. In our case this means the first entry (default=0) will be booted in 5 seconds (timeout=5). If you press Enter during this time, the menu will be displayed.

Once you have a GRUB configuration file, you need to install it, or preferably test it. I'll show you how to do the install first and then show you how to test it using a floppy drive (if you still have one) or a CD.

I'll install GRUB in the partition boot record of the partition containing my CentOS distribution. I use the grub-install command and specify the device where the 512-byte stage1 boot loader should go. In my example, that's /dev/sda11 or (hd0,10) using GRUB notation. See Listing 3. You need to have root authority to write the partition boot record. If you have added or deleted devices you might have to remove your /boot/grub/device.map file and allow grub-install to rebuild is as shown in our example. This won't happen often, but if grub-install throws some odd error that you don’t understand, you might find deleting the device.map file helpful.

Listing 3. Install GRUB Legacy in a partition boot record

[root@attic4-cent ~]# rm /boot/grub/device.map
rm: remove regular file `/boot/grub/device.map'? y
[root@attic4-cent ~]# grub-install /dev/sda11
Probing devices to guess BIOS drives. This might take a long time.
Installation finished. No error reported.
This is the contents of the device map /boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.

(fd0)   /dev/fd0
(hd0)   /dev/sda
(hd1)   /dev/sdb
(hd2)   /dev/sdc
(hd3)   /dev/sdd

As you already learned the standard DOS MBR can't boot a logical partition, so you'll need something else to get this system booted. One option would be to install GRUB in the MBR by doing grub-install /dev/sda which would also install GRUB in the MBR of our disk (/dev/sda). I'll also show you how to do it with GRUB 2 in a moment, but before you commit to either approach step, you might want to test out your setup using a GRUB boot CD.

Building a bootable GRUB rescue CD


Before you reboot your shiny new system, it might be a good idea to build a bootable GRUB CD. First, you prepare a CD image on your hard drive. You need a temporary directory, say grubcd, with subdirectories boot and boot/grub. You then need to copy the stage2_eltorito file from your GRUB distribution files to the grub subdirectory that you just created. Then, use genisoimage to create a bootable .iso image file that you can burn to CD with your favorite burning tool. Listing 4 shows how to create the CD image as grubcd.iso. You do not need root authority to do this. Our stage2_eltorito is in /usr/share/grub/x86_64-redhat. This location might be different on other systems, particularly a 32-bit system. Or, you might find it under /usr/lib/grub. You might be able to locate it using the locate command, also illustrated in Listing 4.

Listing 4. Creating a GRUB bootable CD image

[ian@attic4-cent ~]$ mkdir mkdir -p grubcd/boot/grub
[ian@attic4-cent ~]$ ls /usr/share/grub/
x86_64-redhat
[ian@attic4-cent ~]$ ls /usr/share/grub/x86_64-redhat/stage2_eltorito
/usr/share/grub/x86_64-redhat/stage2_eltorito
[ian@attic4-cent ~]$ locate stage2_eltorito
/usr/share/grub/x86_64-redhat/stage2_eltorito
[ian@attic4-cent ~]$ cp /usr/share/grub/x86_64-redhat/stage2_eltorito grubcd/boot/grub
[ian@attic4-cent ~]$ genisoimage -R -b boot/grub/stage2_eltorito -no-emul-boot \
> -boot-load-size 4 -boot-info-table -o grubcd.iso grubcd
I: -input-charset not specified, using utf-8 (detected in locale settings)
Size of boot image is 4 sectors -> No emulation
Total translation table size: 2048
Total rockridge attributes bytes: 760
Total directory bytes: 4576
Path table size(bytes): 34
Max brk space used 22000
241 extents written (0 MB)

You can boot this CD in an arbitrary PC; it does not have to be one with a Linux system on it. If you boot the CD, it will load the GRUB shell from the CD. When you boot, you get a GRUB boot prompt. Press the tab key or use the help command to see a list of commands available to you. Try help commandname to get help on the command called commandname.

One last thing before you reboot with the CD: You can practice some of the GRUB commands that are available in the GRUB shell from your Linux command line. Listing 5 illustrates the grub command and some of the commands available, including the ability to display the menu and see that it is what you want. Some commands, such as find, require root authority, so my example uses that. Also note that when you attempt to load the first config entry by pressing Enter, GRUB crashes with a segmentation fault. Remember that you can practice some of the GRUB shell commands from the Bash command line, but not all. Up and down arrow keys might not work either. Again, a long kernel line is split using \.

Listing 5. The GRUB command line

[root@attic4-cent ~]# grub
Probing devices to guess BIOS drives. This might take a long time.


    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)

 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename.]
grub> help rootnoverify
help rootnoverify
rootnoverify: rootnoverify [DEVICE [HDBIAS]]
    Similar to `root', but don't attempt to mount the partition. This
    is useful for when an OS is outside of the area of the disk that
    GRUB can read, but setting the correct root device is still
    desired. The items mentioned in `root' which derived
    from attempting the mount will NOT work correctly.
grub> find /boot/grub/menu.lst
find /boot/grub/menu.lst
 (hd0,0)
 (hd0,7)
 (hd0,10)
grub> configfile (hd0,10)/boot/grub/menu.lst
configfile (hd0,10)/boot/grub/menu.lst

Press any key to enter the menu


    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)

-------------------------------------------------------------------
 0: CentOS (2.6.32-504.23.4.el6.x86_64)
 1: CentOS 6 (2.6.32-504.el6.x86_64)
 2: Other
-------------------------------------------------------------------

      Use the ^ and v keys to select which entry is highlighted.
      Press enter to boot the selected OS, 'e' to edit the
      commands before booting, 'a' to modify the kernel arguments
      before booting, or 'c' for a command-line.

The selected entry is 0     Highlighted entry is 0:

  Booting 'CentOS (2.6.32-504.23.4.el6.x86_64)'

root (hd0,10)
 Filesystem type is ext2fs, partition type 0x83
kernel /boot/vmlinuz-2.6.32-504.23.4.el6.x86_64 ro \
root=UUID=2f60a3b4-ef6c-4d4c-9ef4-50d7f75124a2 rd_NO_LUKS rd_NO_LVM \
LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=128M  \
KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
   [Linux-bzImage, setup=0x3400, size=0x3f2790]
Segmentation fault (core dumped)

In this example, there are GRUB configuration files on three different partitions on the first hard drive, including the one built for CentOS on (hd0,10) or /dev/sda11. Listing 5 loads the GRUB menu from (hd0,10) using the configfile command.

You can explore these grub commands in the GRUB manual. Try typing info grub in a Linux terminal window to open the manual.

If you still have a floppy disk, you can install GRUB on a floppy using a command such as
grub-install /dev/fd0
, where /dev/fd0 corresponds to your floppy drive. You should unmount the floppy before installing GRUB on it.

Booting with GRUB legacy


Now you are ready to reboot your system using the GRUB CD that you just built. If your BIOS is not set up to boot automatically from a CD or DVD if present, then you might need to press some system-specific key (F8 on my BIOS) to choose a boot device other than your hard drive. The CD boots to a GRUB prompt as shown in Figure 1.

Figure 1. Booting your GRUB CD

LPI Tutorials and Materials, LPI Guides, LPI Certifications, LPI Certifications, LPI Learning

In this example, I used the find command to find GRUB config files called menu.lst and found 3, including my CentOS GRUB configuration file on device (hd0,10) or /dev/sda11. I then used the root command to set )hd0,10) as the root for further file operations. I installed GRUB in the partition boot record of (hd0,10), So I use the chainloader command to tell grub to boot whatever boot loader is in the first sector of (hd0,10). Finally I use the boot command to boot this new loader (GRUB again in our case). The result is shown in Figure 2

Figure 2. The CentOS Grub menu

LPI Tutorials and Materials, LPI Guides, LPI Certifications, LPI Certifications, LPI Learning

In this case press Enter to see the menu. Otherwise the hiddenmenu option simply displays the line being booted and a countdown timer.

Editing in the GRUB shell


Now, I show you how to use the GRUB shell to edit the configuration. For this purpose, you will boot in single user mode, but you can change any of the lines or even add or delete whole configuration lines if necessary. For example, you can add a complete root line if you had forgotten it. You press e to edit the configuration, then use the down arrow to highlight the kernel line. The result is shown in Figure 3.

Figure 3. Editing the kernel line

LPI Tutorials and Materials, LPI Guides, LPI Certifications, LPI Certifications, LPI Learning

Press e again and then type the word single at the end of the line, as shown in Figure 4.

Figure 4. Editing the kernel line

LPI Tutorials and Materials, LPI Guides, LPI Certifications, LPI Certifications, LPI Learning

Finally, press Enter to return to the screen you saw in Figure 2, then b to boot CentOS into single user mode. When the system boots, you will have a root prompt. You can use this mode to make emergency repairs to a system that won't boot normally.

At this point, you can repeat the previous process to boot into normal graphical mode or whatever mode you had set up your system to boot to. If you wanted GRUB to control all booting on the system, you would now do 
grub-install /dev/sda
to install GRUB in the MBR of /dev/sda. You'll see other ways to manage your booting as you proceed through this tutorial.

Related Posts

0 comments:

Post a Comment