grub2 - shawfdong/hyades GitHub Wiki

On my HP xw8600 Workstation, I used to dual-boot between Windows 7 and CentOS 6. For Windows 7, the boot sector loads the Windows Boot Manager (hidden system file BOOTMGR in the System Reserved Volume or on the root of the local disk), accesses the BCD (Boot Configuration Data) store and uses the information to load the operating system; For CentOS 6, the native boot loader is GRUB version 1 (GRUB legacy). There are two (2x) 2TB hard drives in the HP xw8600 Workstation. My original plan was to install Windows 7 & Windows Boot Manager on the first disk, and CentOS 6 & GRUB legacy on the second disk; and to use Windows Boot Manager to chain load GRUB legacy.

But despite much effort, I couldn't find a way for Windows Boot Manager to load a boot loader on a different disk! This is simply baffling to me, because it means that we could not even dual-boot two Microsoft operating systems (e.g., Windows 7 and Windows Server 2008) that are installed on 2 different disks in the same computer. Maybe the myopic Microsoft engineers couldn't imagine there could be 2 hard drives in a single computer! Nowadays it is fashionable to bash Steve Ballmer for Microsoft's decline. But this was not Ballmer's fault; this is sheer incompetence of the MS engineers who developed Windows Boot Manager!

I ended up creating a small (512 MB) boot partition (/dev/sda3) for CentOS 6 on the first disk and I installed GRUB on the first sector of that partition. The partition scheme is as follows:

# fdisk -l
-----------------------------------------------------------------
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      206847      102400    7  HPFS/NTFS/exFAT
/dev/sda2          206848  1859028991   929411072    7  HPFS/NTFS/exFAT
/dev/sda3      1859028992  1860077567      524288   83  Linux
/dev/sda4      1860077568  3907026943  1023474688    f  W95 Ext'd (LBA)
/dev/sda5      1860079616  3907026943  1023473664    7  HPFS/NTFS/exFAT
/dev/sdb1            2048  3624402943  1812200448   83  Linux
/dev/sdb2      3624402944  3870162943   122880000   83  Linux
/dev/sdb3      3870162944  3890642943    10240000   83  Linux
/dev/sdb4      3890642944  3907028991     8193024    5  Extended
/dev/sdb5      3890647040  3907028991     8190976   82  Linux swap / Solaris

Note that /dev/sda1 is Windows 7's hidden recovery partition. The scheme did allow me to use Windows Boot Manager as the main boot loader for dual-booting Windows 7 & CentOS 6.

Unfortunately, that dual-boot scheme broke down recently when I replaced CentOS 6 with CentOS 7 (still keeping the old partition scheme and Window 7). The native boot loader for CentOS 7 is GRUB version 2 (grub2). When installing CentOS 7, it didn't give me an option to choose where to install grub2, as it had done for CentOS 6. It simply overwrote the MBR of the first disk — grub2 usurped the role of main boot loader! However, when I rebooted the machine, I found there was no entry for Windows 7 in the grub2 menu! How would we add the menu entry for booting Windows 7?

To add a boot entry in GRUB legacy, it is a simple affair of editing the text file /boot/grub/menu.lst. But grub2's equivalent, /boot/grub2/grub.cfg, starts with the following warning:

#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub2-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

So there is an extra level of indirection! Now we need to create a custom script to add the Windows entry in the grub2 menu.

Create a file /etc/grub.d/15_windows, with the following content:

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

Make the script executable:

# chmod +x /etc/grub.d/15_windows

Update the grub2 configuration file:

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

/boot/grub2/grub.cfg will be updated, with the following menuentry for Windows 7:

### BEGIN /etc/grub.d/15_windows ###
menuentry "Windows 7" {
set root=(hd0,1)
chainloader +1
}
which is simply the standard output of the script /etc/grub.d/15_windows. Note that set root=(hd0,1) means that the root of Windows is on the first partition (hd0,1) of the first disk (hd0,1), which is Windows 7's hidden recovery partition — see above. Apparently, the developer of grub2 can't decide whether the index of an array should start at 0 (as in C) or 1 (as in Fortran)!

In the end, it works. But I can't resist to feel that grub2 must have been written by some of Richard Stallman's faithful disciples, because it shares the distinctive traits of Stallman's software: bloated, ugly and confusing!

⚠️ **GitHub.com Fallback** ⚠️