Codementor Events

GRUB and GRUB2

Published Dec 20, 2018

Learn about GRUB and GRUB2 in this article by Philip Inshanally, an industry professional with over 17 years of experience with his own consulting firm which provides local and remote support around the world; focusing towards designing, planning, implementing and documenting to name a few.

This article will discuss the boot managers whose jobs are to present the boot menu, from which the user has the options to select which operating system/Linux kernel to load or edit. First, we will focus on GRUB and then move on to GRUB2.

GRUB

GRUB stands for Grand Unified Bootloader. GRUB is primarily used for booting Linux distributions. However, GRUB can work with other boot loaders. A common use-case scenario is for dual booting with a Microsoft operating system; it does this by doing a hand-off to the Windows bootloader for Microsoft operating systems.

GRUB uses the /boot/grub/grub.conf file. Sometimes, you will see /boot/grub/menu.lst, but this file, is simply a symbolic link to /boot/grub/grub.conf. Using the CentOS 6.5 distro, run the following command:

[root@localhost ~]# ls -l /boot/grub
total 274
 -rw-r--r--. 1 root root 63 Jun 20 01:47    device.map
 -rw-r--r--. 1 root root 13380 Jun 20 01:47 e2fs_stage1_5
 -rw-r--r--. 1 root root 12620 Jun 20 01:47 fat_stage1_5
 -rw-r--r--. 1 root root 11748 Jun 20 01:47 ffs_stage1_5
 -rw-------. 1 root root 769 Jun 20 01:48   grub.conf
 -rw-r--r--. 1 root root 11756 Jun 20 01:47 iso9660_stage1_5
 -rw-r--r--. 1 root root 13268 Jun 20 01:47 jfs_stage1_5
lrwxrwxrwx. 1 root root 11 Jun 20 01:47    menu.lst -> ./grub.conf
 -rw-r--r--. 1 root root 11956 Jun 20 01:47 minix_stage1_5
 -rw-r--r--. 1 root root 14412 Jun 20 01:47 reiserfs_stage1_5
 -rw-r--r--. 1 root root 1341 Nov 14 2010   splash.xpm.gz
 -rw-r--r--. 1 root root 512 Jun 20 01:47    stage1
 -rw-r--r--. 1 root root 126100 Jun 20 01:47 stage2
 -rw-r--r--. 1 root root 12024 Jun 20 01:47  ufs2_stage1_5
 -rw-r--r--. 1 root root 11364 Jun 20 01:47  vstafs_stage1_5
 -rw-r--r--. 1 root root 13964 Jun 20 01:47  xfs_stage1_5
 [root@localhost ~]#

From the preceding output, we can see /boot/grub/grub.conf and also the symbolic link /boot/grub/menu.lst.We can view the actual /boot/grub/grub.conf file:

[root@localhost ~]# cat /boot/grub/grub.conf
 # grub.conf generated by anaconda
 #
 # Note that you do not have to rerun grub after making changes to this file
 # NOTICE: You have a /boot partition. This means that
 # all kernel and initrd paths are relative to /boot/, eg.
 # root (hd0,0)
 # kernel /vmlinuz-version ro root=/dev/sda2
 # initrd /initrd-[generic-]version.img
 #boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
titleCentOS (2.6.32-431.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=05527d71-25b6-4931-a3bb-8fe505f3fa64 rd_NO_LUKSrd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DMrhgb quiet
initrd /initramfs-2.6.32-431.el6.x86_64.img
 [root@localhost ~]#

From the preceding output, the common options would be the following.

• default=0 means it is the first entry to boot from the menu
• timeout=5 gives the amount of seconds (5 in that case) that the menu will be displayed for before the Linux kernel is booted or the Windows boot loader gets a hand-off from GRUB.
• splashimage=(hd0,0)/grub/splash.xpm.gz is the background image of the boot menu
• root (hd0,0) refers to the first hard disk and the first partition on the first hard disk

GRUB2

GRUB2 uses a more programmatic approach in the way the menu is presented. At first glance, GRUB2 may look intimidating, but rest assured that it's not as complicated as it appears to be. The syntax is similar to a programming language, with lots of if...then statements. Here is what /boot/grub/grub.cfg on a CentOS 7 system looks like:

[root@localhost ~]# cat /boot/grub2/grub.cfg
 #
 # DO NOT EDIT THIS FILE
 #
 # It is automatically generated by grub2-mkconfig using templates
 # from /etc/grub.d and settings from /etc/default/grub
 #
### BEGIN /etc/grub.d/00_header ###
set pager=1
if [ -s $prefix/grubenv ]; then
load_env
fi
if [ "${next_entry}" ] ; then
set default="${next_entry}"
setnext_entry=

save_envnext_entry
setboot_once=true
else
set default="${saved_entry}"
fi

Some of the following output is omitted for brevity. Following shows the last part of /boot/grub/grub.cfg:

### BEGIN /etc/grub.d/10_linux ###
menuentry 'CentOS Linux (3.10.0-693.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-693.el7.x86_64-advanced-16e2de7b-b679-4a12-888e-55081af4dad8' {
load_video
setgfxpayload=keep
insmodgzio
insmodpart_msdos
insmodxfs
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 --hint='hd0,msdos1' 40c7c63f-1c93-438a-971a-5331e265419b
else
search --no-floppy --fs-uuid --set=root 40c7c63f-1c93-438a-971a-5331e265419b
fi
 linux16 /vmlinuz-3.10.0-693.el7.x86_64 root=UUID=16e2de7b-b679-4a12-888e-55081af4dad8 rocrashkernel=auto rhgb quiet LANG=en_US.UTF-8
 initrd16 /initramfs-3.10.0-693.el7.x86_64.img
 }
 ### END /etc/grub.d/10_linux ###

So, to interpret the /boot/grub/grub.cfg file, we look for lines that start with menuentry. These lines start theactual menu entry for an operating system, such as a Linux distribution or a Windows OS.

Working with GRUB

Now we're going to interact with GRUB. We will add a custom boot entry. This will be presented upon reboot. We will use the vi command, which will open /boot/grub/grub.conf in the visual editor. Before you work with GRUB, always make a backup copy of your /boot/grub/grub.conf.

[root@localhost ~]# cat /boot/grub/grub.conf
 # grub.conf generated by anaconda
 #
 # Note that you do not have to rerun grub after making changes to this file
 # NOTICE: You have a /boot partition. This means that
 # all kernel and initrd paths are relative to /boot/, eg.
 # root (hd0,0)
 # kernel /vmlinuz-version ro root=/dev/sda2
 # initrd /initrd-[generic-]version.img
 #boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
titleCentOS (2.6.32-431.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=05527d71-25b6-4931-a3bb-8fe505f3fa64 rd_NO_LUKSrd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DMrhgb quiet
initrd /initramfs-2.6.32-431.el6.x86_64.img
 [root@localhost ~]# vi /boot/grub/grub.conf

Now, we're inside vi. We will press I on the keyboard to enter the insert mode; scroll down using the down-arrow key until we reach the last line, and press then Enter to go to a new line:

# grub.conf generated by anaconda
 #
 # Note that you do not have to rerun grub after making changes to this file
 # NOTICE: You have a /boot partition. This means that
 # all kernel and initrd paths are relative to /boot/, eg.
 # root (hd0,0)
 # kernel /vmlinuz-version ro root=/dev/sda2
 # initrd /initrd-[generic-]version.img
 #boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
titleCentOS (2.6.32-431.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=05527d71-25b6-4931-a3bb-8fe505f3fa64 rd_NO_LUKSrd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DMrhgb quiet
initrd /initramfs-2.6.32-431.el6.x86_64.img
~
 ~
 ~
 -- INSERT --

Next, we will start our entry using the following keywords: title, root, kernel, and initrd. We will insert our own custom values, as shown here:

# grub.conf generated by anaconda
 #
 # Note that you do not have to rerun grub after making changes to this file
 # NOTICE: You have a /boot partition. This means that
 # all kernel and initrd paths are relative to /boot/, eg.
 # root (hd0,0)
 # kernel /vmlinuz-version ro root=/dev/sda2
 # initrd /initrd-[generic-]version.img
 #boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
titleCentOS (2.6.32-431.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=05527d71-25b6-4931-a3bb-8fe505f3fa64 rd_NO_LUKSrd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DMrhgb quiet
initrd /initramfs-2.6.32-431.el6.x86_64.img
titleCompTIA Linux+ (Our.Custom.Entry)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86 ro
initrd /initramfs-2.6.32-431.el6.x86_64.img
 -- INSERT --

Now, we will save and exit vi. We use :wq to save our change(s) and exit vi:

titleCompTIA Linux+ (Our.Custom.Entry)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86 ro
initrd /initramfs-2.6.32-431.el6.x86_64.img
:wq

Based on the preceding output, here is a breakdown of our custom entry:

• The title defines our customer boot entry.
• root (hd0,0) tells it to search for the first hard disk and the first partition on the first hard disk.
• The kernel /vmlinuz-2.6.32-431.el6.x86 ro tells GRUB to look for the location of the Linux kernel. In this case, it's vmlinuz-2.6.32-431.el6.x86 ro (ro means it loads the kernel as read-only).
• inidrd /initramfs-2.6.32-431.el6.x86_64.img specifies the initial RAM disk file to use (this aids the system boot up).

The last step is to reboot our CentOS system and be presented with the GRUB boot menu:
1.PNG

From the preceding output, we can see our new custom boot entry is displayed in GRUB, which is awesome. We can interact in real time, right at the GRUB menu. Let's say we wanted to tag on or remove an option from one of these entries. We would simply press the E key, as shown here:
2.PNG

Now, we can press the E key once again to edit the entry. Let's say we want to specify that the root filesystem resides in /dev/; we would do this as shown in the following screenshot:
3.PNG

Now, we can press the Enter key, which will save our changes and the Esc key to return to the previous screen; we will see the new option added:
4.PNG

From the preceding output, we can see how easy it is to work in real-time at the GRUB boot menu and also how to add a custom boot entry in GRUB.Note that in GRUB, the first hard disk and the first partition are identified as (hd0, 0), whereas in the Linux shell, the first hard disk and first partition are identified as (sda1).

Working with GRUB2

We add a custom boot entry in GRUB2 in a slightly different way from GRUB. In GRUB2, instead of editing the actual /boot/grub/grub.cfg, we work with /etc/default/grub and /etc/grub.d. Let's do a listing of /etc/grub.d to see all available files:

philip@ubuntu:~$ ls -l /etc/grub.d/
total 76
 -rwxr-xr-x 1 root root 9791 Apr 15 2016 00_header
 -rwxr-xr-x 1 root root 6258 Mar 15 2016 05_debian_theme
 -rwxr-xr-x 1 root root 12261 Apr 15 2016 10_linux
 -rwxr-xr-x 1 root root 11082 Apr 15 2016 20_linux_xen
 -rwxr-xr-x 1 root root 1992 Jan 28 2016 20_memtest86+
 -rwxr-xr-x 1 root root 11692 Apr 15 2016 30_os-prober
 -rwxr-xr-x 1 root root 1418 Apr 15 2016 30_uefi-firmware
 -rwxr-xr-x 1 root root 214 Apr 15 2016 40_custom
 -rwxr-xr-x 1 root root 216 Apr 15 2016 41_custom
 -rw-r--r-- 1 root root 483 Apr 15 2016 README
philip@ubuntu:~$

Before you work with GRUB2, always make a backup copy of your /boot/grub/grub.cfg.From the preceding output, we can see a number of files. Their names start with a number, and the numbers are read in sequential order. Let's say we want to add a custom boot entry in GRUB2. We are going to create a custom entry and name it /etc/grub/40_custom. We will see the following code in vi:

#!/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.
echo "Test Entry"
cat<< EOF
menuentry "CompTIA_LINUX+" {
set root ='hd0,0'
}
 EOF

From the preceding output, we can see the syntax is a bit similar to programming. In GRUB2, it's an entire programming language. The next step is to save our changes, then run grub-mkconfig (the name implies we're talking about legacy GRUB, but we're actually referring to GRUB2). This depends on the Linux distribution. In CentOS 7, you will see commands that start with grub2:

root@ubuntu:/home/philip# grub-mkconfig
 Generating grub configuration file ...
 #
 # DO NOT EDIT THIS FILE
 #
 # It is automatically generated by grub-mkconfig using templates
 # from /etc/grub.d and settings from /etc/default/grub
 #
### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
sethave_grubenv=true
load_env
fi

Some of the following output is omitted for the sake of brevity:

### BEGIN /etc/grub.d/40_custom ###
 # 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 "Test Entry"
cat<< EOF
menuentry "CompTIA_LINUX+" {
set root ='hd0,0'
}
 EOF

When we run this command, the grub-mkconfig command finds the custom entry. This generates a new boot menu. Upon the the next reboot of the system, we will see the new boot menu. We can also change options in /etc/default/grub, including options such as the default OS, the timer, and so on. Here is the content of /etc/default/grub:

root@ubuntu:/home/philip# cat /etc/default/grub
 # If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
 # For full documentation of the options in this file, see:
 # info -f grub -n 'Simple configuration'
GRUB_DEFAULT=0
 GRUB_HIDDEN_TIMEOUT=0
 GRUB_HIDDEN_TIMEOUT_QUIET=true
 GRUB_TIMEOUT=10
 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
 GRUB_CMDLINE_LINUX_DEFAULT="quiet"
 GRUB_CMDLINE_LINUX="find_preseed=/preseed.cfg auto noprompt priority=critical locale=en_US"

Based on the preceding output, the timer value is set to 10. Also, note that there is a default value of 0. Continuing down the configuration file, we see the following code:

# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console
# 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'
#GRUB_GFXMODE=640x480
# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true
# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY="true"
# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"

Now, let's reboot our Ubuntu system and check out the GRUB2 boot menu:
5.PNG

From the preceding screenshot, we can now see our custom menu option in GRUB2. We can even scroll through the entries and edit them by pressing the E key.Note that in GRUB2, the first hard disk starts with 0 and the first partition starts with 1, unlike in legacy GRUB.

If you found this article interesting, you can explore CompTIA Linux+ Certification Guide to master the concepts and techniques that will help you gain the LX0-103 and LX0-104 certifications on your first attempt. CompTIA Linux+ Certification Guide will help you get to grips with all the modules using practice questions and mock exams, but you’ll also be well prepared to pass the LX0-103 and LX0-104 certification exams. You can avail all of Packt’s books for just $5 till January 21, 2019. So what are you waiting for? Avail the offer today and become an exceptional IT professional!

Discover and read more posts from PACKT
get started
post commentsBe the first to share your opinion
Show more replies