Dual boot Windows XP and CentOS 5 with NTLDR

I wanted to install CentOS onto a spare partition on a machine with Windows XP already installed, leaving the MBR as it was and using the NTLDR bootloader. CentOS installed fine onto the partition but the installer only seemed to offer two options for setting up GRUB: installing to the MBR or not installing at all; there wasn’t an obvious way of getting it to install onto the boot sector of the CentOS partition. There might have been some more advanced options in the installer but I didn’t have the time to experiment (I’m fairly new to CentOS/Red Hat/Fedora, being more of a Slackware and Debian-family user normally), so I elected to not install and set up afterwards. This leaves CentOS unbootable, but with a bootdisk like sysresccd and a basic knowledge of GRUB it’s fairly straitforward to fix this. Here’s a rundown on what I did, which might be useful in a similar situation or when having trouble with a b0rked GRUB installation.

Obviously the partition details specified below are derived from the system I was working on, where the hard disk is/dev/sda, Windows is on /dev/sda1 and CentOS on /dev/sda2. There is a swap partition on /dev/sda3 but it isn’t relevant for this exercise.

Also, you follow these instructions at your peril. It is all too easy to screw up and make your entire system unbootable, lose data or just render the whole process more painful than it has to be. Back-up, read relevent documentation before you begin, back-up, check the sytax of the commands you type before executing them and have I said back-up?

  1. First, if you are not familiar with GRUB browse the documentation. The steps below are fairly terse and not pitched at total beginners. They also assume a familiarity with basic shell commands.
  2. Once the CentOS install is complete reboot using sysresccd.
  3. Create a mount point for CentOS’s root partition, e.g. /boot/centos, and mount it:

    # mkdir /boot/centos
    # mount -t ext3 /dev/sda2 /mnt/centos
  4. Mount your Windows partition (/mnt/windows is usually present):

    # ntfs-3g /dev/sda1 /mnt/windows
  5. Copy the following files:

    # cp /mnt/centos/usr/share/grub/i386-redhat/stage1 /mnt/centos/boot/grub
    # cp /mnt/centos/usr/share/grub/i386-redhat/stage2 /mnt/centos/boot/grub
    # cp /mnt/centos/usr/share/grub/i386-redhat/*_stage1_5 /mnt/centos/boot/grub
  6. Launch GRUB. Fortunately sysresccd and CentOS 5 both use GNU GRUB 0.97, so there are no compatibility problems.

    # grub
  7. This will dump you into GRUB’s command interpreter. You need to set the root drive and then install GRUB into the partition’s boot sector as follows; output from the commands represented by elipses but note that you might get warning messages – as long as the final message indicates success, you should be fine. Oh, and be careful to ensure you install this onto the correct partition – remember GRUB starts counting partitions at 0, not 1 like Linux!

    grub> root (hd0,1)
    ...
    grub> setup (hd0,1)
    ...
    grub> quit
  8. Next you need to create the file that NTLDR will use to hand-off booting CentOS to GRUB, basically the first 512 bytes of the partition:

    dd if=/dev/sda2 of=/mnt/windows/bootsect.lnx bs=512 count=1
  9. Next modify /mnt/windows/boot.ini to include a line for CentOS at the end. The cautious may wish to reboot into Windows to modify this file.

    C:\bootsect.lnx="CentOS 5"
  10. Reboot. You should now see a boot menu offering you Windows and CentOS 5. If you don’t, check C:\boot.ini for a timeout stanza and edit accordingly. Selecting CentOS 5 will dump you back into GRUB’s shell – GRUB is installed but doesn’t have a configuration file set up. You can use the following commands to boot CentOS 5:

    grub> root (hd0,1)
    grub> kernel /boot/vmlinuz-2.6.18-8.el5 ro root=/dev/sda2 rhgb quiet
    grub> initrd /boot/initrd-2.6.18-8.el5.img
    grub> boot
  11. CentOS 5 will then boot and you can complete the installation. Depending upon your choices, you may need to reboot again using the above procedure.
  12. Once complete you can configure GRUB to boot automatically by creating /boot/grub/device.map, /boot/grub/grub.conf and /boot/grub/menu.lst. The device.map file should just contain a single line mapping the linux hard disk device to a GRUB device notation:

    (hd0)   /dev/sda

    The grub.conf file specifies the various boot options, in our case a fairly straitforward single kernel and ramdisk image:

    default=0
    timeout=5
    hiddenmenu
    title   CentOS (2.6.18-8.el5)
            root (hd0,1)
            kernel /boot/vmlinuz-2.16.18-8.el5 ro root=/dev/sda2 rhgb quiet
            initrd /boot/initrd-2.6.18-8.el5.img

    Then, with /boot/grub as your working directory, do:

    ln -s grub.conf menu.lst
  13. Now when you reboot and select CentOS from the Windows boot menu GRUB should automatically start CentOS after a five second timeout. You can add additional entries to the grub.conf file – custom or testing kernels, memtest86+, etc – then view the menu within the timeout period to select them.

I’m more than happy to get feedback on stuff like this, even if it’s just to tell me I’m an idiot and could’ve done it in a simpler way. There’s no commenting system here at the moment, but please feel free to email me with questions or suggestions, or even if you just found this useful.