Dual Boot - Windows on RedHat 7
Grub2 Configuration Dual Boot Windows on Red Hat Enterprise 7

Grub2 is the default boot loader. We will configure a system to dual boot Red hat 7 and Windows 7. And we also look at grub2, how it is setup.

To dual boot Windows 7 and Red Hat 7 first install Windows 7 and install Red Hat 7. After install both the Operating system you are not able to boot the Windows system and you will not get option to boot windows. To boot windows system need to configure Grub2 in Red Hat.

Grub2 Important Files and Directories

Under the /boot directory you have two sub-directories, one for grub and one for grub2. We will use grub2

# cd /boot/grub2

In this directory you’ll see a number of files and directories:

# ls -l
-rw-r--r--. 1 root root 64 Jul 22 20:27 device.map
drwxr-xr-x. 2 root root 24 Jul 22 20:27 fonts
-rw-r--r--. 1 root root 5044 Jul 23 21:23 grub.cfg
-rw-r--r--. 1 root root 1024 Jul 23 21:15 grubenv
drwxr-xr-x. 2 root root 8192 Jul 22 21:11 i386-pc
drwxr-xr-x. 2 root root 4096 Jul 22 21:11 locale
drwxr-xr-x. 3 root root 19 Jul 22 20:23 themes

If you cat the device.map file you will see the translation between device and grub2 device names. In this case there is one disk /dev/sda which uses the grub2 device name hdO;

# cat device.map
# this device map was generated by anaconda
(hdO)        /dev/sda

Another important file is the grub.cfg file which is the file where the configuration script is saved (by grub2-mkconfig, more on that later). If you cat the file you’ll see that it is a complex script (for beginners), but the important parts are in the header. If you give the following head command, you will see the top of the file:

# head 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/OO_header ###

The first thing you will notice is the line "DO NOT EDIT THIS FILE". It then explains that you need to use the grub2 template file under /etc/grub.d or the grub2 default settings file /etc/default/grub.

Default Grub Config File

We first take a look at the default grub2 config file under /etc/default. As mentioned this is where the default config settings are made such as the time before the default menu entry is booted (default is 5 seconds, see variable: GRUB_TIMEOUT).

# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/swap vconsole.font=latarcyrheb-sun16
rd.lvm.lv=centos/root crashkernel=auto vconsole.keymap=us rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

So let us change the GRUB_TIMEOUT variable to 10 seconds using vi (or any other editor you like). Let’s also add a variable that is not in the default grub configuration which is: GRUB_DISABLE_LINUX_UUID="true" and save the file. This last variable will put the absolute device names instead of UUID- i.e. /dev/sdXY. (Note this is for example purpose only, I will explain later on).

Now to activate this configuration, you will need to generate a new /boot/grub2/grub.cfg file using the tool grub2-mkconfig.

grub2-mkconfig

If you run the tool grub2-mkconfig you will see a lot of text (the script that is generated on the screen). A common mistake people make is to think that this will generate and write the config file to disk. This is not so! The script will only be displayed on the screen, not to disk. (To verify you could now reboot and see if the boot timeout is set to 10 seconds).

To write to disk you need to use the following command:

# grub2-mkconfig -o /boot/grub2/grub.cfg

Now the default settings should be written to disk (reboot to verify, notice the boot timeout).

With the GRUB_DISABLE_LINUX_UUID entry in the default config you’ll see something like this when you run grub2-mkconfig :

# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-123.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-123.el7.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-123.4.2.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-123.4.2.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-957d0004a0aa4a6080dd929ffd92555c
Found initrd image: /boot/initramfs-0-rescue-957d0004a0aa4a6080dd929ffd92555c.img
done

Now remove the line from the default config (remember it was for demonstration purpose only, more on that later) and save the file. Rerun the configure command:

# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
No device found for PV 84ARqO-Fhcl-dNC0-dVa0-7EpR-Nl9K-pzdyQR.
No device found for PV 84ARqO-Fhcl-dNC0-dVa0-7EpR-Nl9K-pzdyQR.
No device found for PV 84ARqO-Fhcl-dNC0-dVa0-7EpR-Nl9K-pzdyQR.
No device found for PV 84ARqO-Fhcl-dNC0-dVa0-7EpR-Nl9K-pzdyQR.
Found linux image: /boot/vmlinuz-3.10.0-123.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-123.el7.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-123.4.2.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-123.4.2.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-957d0004a0aa4a6080dd929ffd92555c
Found initrd image: /boot/initramfs-0-rescue-957d0004a0aa4a6080dd929ffd92555c.img
done

Note : ignore the "No device found for PV.." message, but as you can see UUID's are now used.

For beginners the UUID's can be very confusing because people read the absolute device notation much easier for instance /dev/sda1. But the UUID is much saver to use, because if you re-arrange partitions in partition table (for example insert/delete partitions) and partition numbers changed- grub can't find the kernel to boot. If you use UUID, even when you re-arranging the partitions things won't break. That's why UUID is preferred, but I agree that it much harder to read. (So leave out the variable mentioned earlier).

Template /etc/grub.d Directory

Let’s goto the /etc/grub.d directory and see what is done in this directory.

# ls -l
total 68
-rwxr-xr-x. 1 root root 8698 Jun 30 18:16 00_header
-rwxr-xr-x. 1 root root 9517 Jun 30 18:16 10_linux
-rwxr-xr-x. 1 root root 10275 Jun 30 18:16 20_linux_xen
-rwxr-xr-x. 1 root root 2559 Jun 30 18:16 20_ppc_terminfo
-rwxr-xr-x. 1 root root 11110 Jun 30 18:16 30_os-prober
-rwxr-xr-x. 1 root root 214 Jul 22 21:55 40_custom
-rwxr-xr-x. 1 root root 216 Jun 30 18:16 41_custom

You see that the directory contains different script (that need to be executable, note that for later!) that are used to generate the /boot/grub2/grub.cfg file by the grub2-mkconfig POSIX shell script. These template are used in order (00 to 41). You may edit these files, but you have to know what you are doing.

Dual Boot Windows 7 and Red Hat 7

If you reach it until here, you should know the basics of grub2 at least enough to start editing (and maybe break things)

In our case we have multiple disks on the machine but we have installed Windows and Red Hat on the same SSD disk.

# fdisk -l |grep "Disk /dev"
Disk /dev/sda: 120.0 GB, 120034123776 bytes, 234441648 sectors
Disk /dev/sde: 3000.6 GB, 3000592982016 bytes, 5860533168 sectors
Disk /dev/sdb: 3000.6 GB, 3000592982016 bytes, 5860533168 sectors
Disk /dev/sdc: 3000.6 GB, 3000592982016 bytes, 5860533168 sectors
Disk /dev/sdd: 3000.6 GB, 3000592982016 bytes, 5860533168 sectors
Disk /dev/mapper/centos-swap: 8396 MB, 8396996608 bytes, 16400384 sectors
Disk /dev/mapper/centos-root: 35.9 GB, 35907436544 bytes, 70131712 sectors
Disk /dev/mapper/centos-home: 17.5 GB, 17527996416 bytes, 34234368 sectors

We first installed Windows 7 and used half of the first SSD disk and left the rest unpartitioned. Then we installed Red Hat Enterprise 7 and used the other half of the disk. If we give the command blkid we see the following layout:

# blkid
/dev/block/253:0: UUID="ba700a61-092c-4042-a134-2876ae49e741" TYPE="swap"
/dev/sda1: LABEL="Door systeem gereserveerd" UUID="76449D01449CC571" TYPE="ntfs"
/dev/sda2: UUID="944A9D9F4A9D7F24" TYPE="ntfs"
/dev/sda3: UUID="5abb20e8-9493-46bc-89bd-887452403619" TYPE="xfs"
/dev/sda5: UUID="uJpBkk-ugcH-xrOR-DIZu-eJnJ-0g6a-ImDwo2" TYPE="LVM2_member"
/dev/dm-2: UUID="5432cf99-6222-486b-9e21-f9dd7a663b48" TYPE="xfs"
/dev/dm-1: UUID="57f5fade-253b-442d-be1a-d50906edb3d6" TYPE="xfs"

As you can see our Windows 7 partition is on /dev/sda1, which is hdO,1 in Grub2. Note that sda disk is 0 and a sdb is 1. The partition however start with 1 for sda1 or sdb1 for a second disk. (Different from grub, which had the first partition on hdO,O) The linux partition is in our case /dev/sda3, which is in grub2 hd0,3. But if you look in the generated /boot/grub2/grub.cfg file:

# cat /boot/grub2/grub.cfg |grep msdos
insmod part_msdos
set root='hdO,msdos3'
search --no-floppy --fs-uuid --set=root --hint-bios=hdO,msdos3 –hint-efi=hdO,msdo

you’ll see that the following notation is generated: ‘hd0,msdos3’ (which is sda3).

So now let’s add a template for Windows 7. You can do this in 40_custom, but we like to add it between 10 and 20. So vi /etc/grub.d/15_windows7:

#! /bin/sh -e
echo "Adding Windows 7" >&2
cat < menuentry "Windows 7" {
set root=(hd0,1)
chainloader +1
}
EOF

Note : make sure the script has executable rights (if not use: chmod +x /etc/grub.d/15_windows7). If the script has no executable rights the grub2-mkconfig command won’t pickup the script (you won’t see "Adding Windows 7" when you run grub2-mkconfig -o /boot/grub2/grub.cfg)

Note2 : sometimes when the script is cut and paste from the website the " are messed up. In that case you get an error running grub2-mkconfig. In that case just retype the " in the script and rerun grub2-mkconfig.

You can see we add (hdO,1) which is /dev/sda1 to boot Windows (this is where the boot manager of windows resides). Now run the grub2-mkconfig -o /boot/grub2/grub.cfg to generate and save a new config file. Reboot and select your windows partition to boot (of course you should enter your disk, retry if windows won’t boot, because you maybe have selected the wrong disk). The grub2 menu should look like something like this :

Red Hat 7
Red Hat 7 Rescue
Windows 7

The first entry is selected at default. What if we want the Windows 7 partition to be the default to boot.

grub2-set-default

With the command grub2-set-default you can set the default selected menu-entry at boot time. So in this case we want Windows 7 to be the default. Run the following command and reboot:

grub2-set-default 2

Note : we start counting by zero and not one. So zero is Red Hat 7 and so on.

You'll see during booting that Windows 7 is highlighted by default. Rerun the command after booting to Linux, but now with O for Red Hat 7 as default.