Grub2 Configure Dual Boot Windows on Red Hat Enterprise 7
In this Linux CentOS 7 or Red Hat Enterprise 7 we will take a look at Grub2 which is become the default boot loader on the previous mentioned distributions. We will configure a system to dual boot CentOS 7 and Windows 7. And we also look at grub2 in general, how it is setup.
Grub2 Important Files and Directories
Under the /boot directory you have two sub-directories, one for grub and one for grub2. We of course will use grub2.
# cd /boot/grub2
In this directory you’ll see a number of files and directories:
# ls -l
total 32
-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 devices and grub2 device names. In this case there is one disk /dev/sda which uses the grub2 device name hd0:
# cat device.map
# this device map was generated by anaconda
(hd0) /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 commando, 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/00_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 commando:
# 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 CentOS 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 CentOS 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 CentOS 7 (or 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 hd0,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 hd0,0) 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='hd0,msdos3'
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos3 --hint-efi=hd0,msdos3 --hint-baremetal=ahci0,msdos3 --hint='hd0,msdos3' 76f0fe64-3654-4dc2-b914-45d8a78d4829
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 <<EOF
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 (hd0,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:
CentOS 7
CentOS 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 CentOS 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 0 for CentOS 7 as default.
That’s all for this tutorial. If you made it to here you should now have a basic knowledge of grub2, at least to make minor changes to the configuration. Good luck in your grub2 endeavours.
Dear Bro,
Thanks for writing, it’s very helpful for me 🙂
Regards,
Tarmizi H
Very helpful; many thanks!
Saga.
Worked perfectly with RHEL 7! Thanks!
Worked well.
Frustrating that OS Prober does not seem to do well with Cent OS, though no issue with Ubunto finding the Windows 7/8/10 partion.
sir,
thank your this is help full for me.
I thought I trashed my windows partition when I installed Centos7. This got me working again! Thank you.
you saved the day. i’ve been trying to get it to work for almost a day
This worked perfectly for Windows 10 and CentOS 7. You saved my day. Thank you!!!
Thank you
Worked fine for getting windows back but cant getting option to dual boot ie only windows starts directly no option for booting RHEL 7
Perfect! Just the help I needed. Thanks for making this page
Well written doument. Work for me
Thank you sir
Confirmed works with RHEL 7.2 and Windows Server 2008 R2. Thank you.
This was a very helpful page. I was trying to get my windows drive back (Ya i know but sadly I need it for some apps) and came across this info.
Great step by step.
Thank you for posting it.
Its done… Done with rhel 7 and win 7…thanx a lot….
This was the most helpful and simple resolution I have ever had from the Linux Help Tools. Well done!!
Thank you so much. This just saved me a lot of research. I found your page, followed the instructions and it is working with Windows 7 64bit and Red Hat v7.2 Enterprise Workstation.
You are the best!
Thanks – after quite some searching this was very helpful!
Thank you, this worked for me with
Windows 10 Pro (10.0.14393) and Redhat 7.3 (RHEL)
Thanks, this work for me on rhel 7.3
Perfect solution for Dual boot.
I have a UEFI computer. The file is /etc/grub2-efi.cfg
I have another second SSD in the computer, with CentOS 7 installed. How can I add a menuentry to the boot options?
Its working. Thanks a lot! Though I didnt get the concept behind this What we did.But followed the steps n ots working now
Super Bro!!!
Thank you, this worked for me with
Windows 10 and CentOS 7