Saturday, November 26, 2011

Getting the Grub Boot Loader to Recognize Windows XP

The title for this article is a little
bit long. I messed up my Debian installation
by being careless about upgrading from Debian
Lenny to Debian Squeeze.

I tried to repair the poblem myself but gave
up rather quickly. Here's some of the things
that I discovered that could have prevented
the problem in the first place:

Fix My Broken Debian Package

After having messed up my Debian installation
after years of stability, I've decided to upgrade
to Debian Squeeze by doing a brand new install.

A brand new install for me means unplugging my
old hard drive and plugging in a new hard drive
and going to work. Currently I'm trying to install
both Windows XP and Debian Squeeze. I wish it
were easier for me to do.

The current problem I'm having is with Grub. It's
weird but the Debian setup menus recognize Windows
XP just prior to installing Grub. I get a message
saying that Windows XP Home Edition is recognized.
However, when I install Grub, it is not recognized.
Weird!

Here's my first attempt to learn more about Grub:

GRUB bootloader - Full tutorial

The above tutorial tells me that there are 2 versions of
Grub available, generally speaking. There is Grub legacy
and there is Grub 2.

Here's a web page that tells me how I can find out
whether or not I'm running Grub 2 or Grub legacy:

GNU GRUB Manual 1.99

The above web page seems to suggest 3 steps you can
use to determine which version of Grub you are running:

  1. Look under the directory (folder) /boot/grub/
  2. Look for a file called grub.cfg
  3. If you find grub.cfg you are running
    Grub 2
  4. If you don't find grub.cfg, I would guess
    that you are running Grub Legacy
  5. If you find a file called menu.lst,
    you are definitely running Grub Legacy

I'm discovering all of thsi as I write. It's really
a very simple thing. If your Grub configuration file
is called grub,cfg you are running Grub 2. If
your Grub configuration file is called menu.lst
you are running Grub Legacy.

OK. I just learned something important. You can
generate a new grub.cfg file by running this
command at the prompt:

grub-mkconfig

I learned about the grub-mkconfig command here:

Invoking grub-mkconfig

Note that the above command writes to standard output. Thus,
it harmlessly dumps all the changes to your screen instead
of to a file.

Here's how I make it dump the new configureation for Grub
to a temporary file:

grub-mkconfig -o temp

Next, I did an interesting experiment to see
whether my temporary file and the file
called grub.cfg are different:


diff grub.cfg temp >temp2

Wow! I hit paydirt. The only difference
is that the menu entry for Windows XP was
not included in grub.cfg. The total
difference between the two files is that
my file called temp has Windows XP
boot information and grub.cfg does
not.

Here's the contents of temp2, the file I
used to document the difference:

96a97,104
> menuentry "Microsoft Windows XP Home Edition (on /dev/sda1)" {
>       insmod part_msdos
>       insmod ntfs
>       set root='(hd0,msdos1)'
>       search --no-floppy --fs-uuid --set eeccf074ccf03883
>       drivemap -s (hd0) ${root}
>       chainloader +1
> }

OK. I think I'll back up a copy grub.cfg and then make this
change for real. What harm could it do? It only adds information.
It does not delete it.

Some time later . . .

OK. I'm back! It worked! Seems that the
Debian installation software was not recognizing
Windows XP.

Running the following two commands seems to
have done the trick:

cp grub.cfg grub.cfg.bak
grub-mkconfig -o grub.cfg

The first command backs up the configuration file.
The second commmand regenerates the configureation
file.

The lesson? If it doesn't work the first time,
try the same thing in a new way.

So often, it only takes a slight adjustment to make
something work.

Update: February 18, 2012

Something weird happened a couple of days ago.
My copy of grub was totally regenerated without
me requesting it. This was totally unexpected.

The reason this happened seems to be that I had
mounted my old Linux hard drive and then forgot
to unmount it after I was done with it. I then
shut down Linux with the old hard drive mounted.

Since I don't ever intend to boot Linux off the
old hard drive, I had left this old hard drive
unmounted when I generated grub.cfg on
November 22, 2011, as detailed above.

Shutting down my computer with 2 hard drives
mounted seems to have caused grub to
spontaneously regenerate. I'm going to guess
that grub spontaneously regenerated because
I had operating system partitions that could
potentially be mounted that it did not recognize.

My solution to this problem will be simple. I'm
going to regenerate grub.cfg again. Before
I do so, I'll make the following copy:

cp grub.cfg grub.cfg.2012-02-18.old

Next, I regenerate grub with the old hard drive
unmounted. I'll repeat this command from above
to do this:

grub-mkconfig -o grub.cfg

Wow! The above command did not do what I expected.
The following command produces a silent result:

cmp grub.cfg grub.cfg.2012-02-18.old

In other words, leaving the old hard drive unmounted
had absolutely no effect. Regardless of whether or not
the old hard drive is currently mounted, the partitions
there are fully accounted for by grub-mkconfig.

I'm going to guess that this is a change from how
grub-mkconfig used to work. Something seems
to have changed since November 22, 2011.

OK. Time to rethink this. I think I'll leave things
mostly the way they are with 2 exceptions:

  1. I'll comment out the old Windows partition since I
    don't want licensing problems with Microsoft
  2. I'll change the timeout from 5 seconds to
    3600 seconds (1 hour)

I don't know that running an old copy of Windows XP
is going to give me licensing problems but I'd rather
not take a chance. I have no need and no desire to
run the old copy so why make it an issue?

My best guess is that this would not cause a licensing
problem since my copy of Windows XP is a legitimate one.
The reason there are 2 copies is because I reinstalled
Windows XP when I got a new hard drive.

However, since I don't care about the old copy of Windows
XP, other than I use it to retrieve old data files, I'll
err on the side of caution. The only reason I still have
the old copy of Windows XP is that it has old data on it.

Update: February 20, 2012

Looks like I'm not supposed to modify grub.cfg
directly. This web page seems to be saying that there
are better ways to get the result I wish to get:

How to change the GRUB 2 Default Timeout and Boot Order - Ubuntu

The above is for Ubuntu. I'll research this further to
see if it applies to Debian as well.

OK. Just found the web page for Debian's configuration
of Grub:

Debian Grub Wiki

Finally! The above web page tells me how to set the default
timeout. The default timeout is set in this file:

/etc/default/grub

Here's the line that needs to be changed. The number
5 indicates that 5 seconds will pass before grub takes
off and makes a menu selection for you:

GRUB_TIMEOUT=5

Prior to changing this line, I'm going to back
up the file like this:

cp grub grub.bak

The backup copy lets me know I made a change without
having to resort to too much documentation. Now,
here's how I change the line so that Grub waits an
hour before making a menu selection for me:

# Timeout changed by Ed A., 2012-02-20
#GRUB_TIMEOUT=5
GRUB_TIMEOUT=3600

Later, if I wish to discover this change easily,
I can do the following command. The following
command shows me the difference between the 2
files:

/etc/default$ diff grub.bak grub
5c5,7
< GRUB_TIMEOUT=5
---
> # Timeout changed by Ed A., 2012-02-20
> #GRUB_TIMEOUT=5
> GRUB_TIMEOUT=3600

The above diff command uses a left
arrow to indicate what comes out of the file
and a right arrow to indicate what goes back
in. In other words, left arrow to delete
and right arrow to insert.

OK. It is now time to regenerate grub.cfg
with the new default timeout in place. This
command is still silent:

cmp grub.cfg grub.cfg.2012-02-18.old

Now I regenerate grub.cfg:

grub-mkconfig -o grub.cfg

After I regenerate it, I check to see what
changes were made from the old file to the
new file:

/boot/grub# diff grub.cfg.2012-02-18.old grub.cfg
52c52
< set timeout=5
---
> set timeout=3600

OK. Just as I hoped. The above diff command
indicates the timeout of 5 seconds has gone out and
the timeout of 3600 seconds (1 hour) has come in to
replace it.

This is one of the things I love about Linux and Unix.
Little tiny commands, such as the diff command,
yield such wonderful information!

I'm going to try rebooting next.The Grub menu should
be more patient with me this time. Instead of giving
me 5 seconds to make a selection, it will give me an
hour.

OK. I'm back. The Grub menu is now pausing for 3600
seconds, just like I wanted it to. Success!

My next move is going to be to comment out the old
copy of Windows XP in grub.cfg. To the best
of my knowledge, this is the only way to do it. Even
though you are not really supposed to edit grub.cfg
directly, I don't know how else to do it.

First thing I do is confirm that the 8 menu choices
I saw visually on the Grub menu show up in grub.cfg
as menuentry blocks. In doing this, I'm confirming
that menuentry blocks do what I think they do:

/boot/grub$ grep -c menuentry grub.cfg
8

The above grep command tells me that the keyword
menuentry appears 8 times in grup.cfg. Based
on what I saw visually in the actual menu when booting, this
is exactly what I expect.

The next thing I do is I go looking for the menuentry
block
that correlates with my old version of Windows
XP, as well as my old hard drive.

Here, I found it:

menuentry "Microsoft Windows XP Home Edition (on /dev/sdb1)" {
 insmod part_msdos
 insmod ntfs
 set root='(/dev/sdb,msdos1)'
 search --no-floppy --fs-uuid --set 5cf0b47cf0b45dc8
 drivemap -s (hd0) ${root}
 chainloader +1
}

I'm sure that the above is the menuentry block for my
old copy of Windows XP as it says it is found on /dev/sdb1.
Tha's exactly what I expect. If it were the next copy of Windows
XP, it would say /dev/sda1).

My old copy of Windows XP is on sdb and my new copy is on
sda. In other words, I have 2 menuentry blocks. One
is for the old version of Windows XP and one is for the new version
of Windows XP.

Something you may want to be careful of when identifying a
menuentry block and that is the closing curly brace.
Looks like curly braces open and close menuentry blocks
in much the same way that curly braces open and close functions
in C Language.

Looks like a pound sign is the commenting character in
grub.cfg. No big surprise there. A pound sign is
a commenting character in Unix shell scripts and just about
every scripting language that I'm aware of that is of recent
vintage (the last 20 or 30 years or so).

My next move is to comment out the old menuentry block
for my old copy of Windows XP:

#menuentry "Microsoft Windows XP Home Edition (on /dev/sdb1)" {
# insmod part_msdos
# insmod ntfs
# set root='(/dev/sdb,msdos1)'
# search --no-floppy --fs-uuid --set 5cf0b47cf0b45dc8
# drivemap -s (hd0) ${root}
# chainloader +1
#}

Now that I've commented out the menu entry I do not wish to
appear, I'll check that everything looks kosher with the Unix
diff command:

/boot/grub$ diff grub.cfg.2012-02-18.old grub.cfg
52c52
< set timeout=5
---
> set timeout=3600
105,112c105,112
< menuentry "Microsoft Windows XP Home Edition (on /dev/sdb1)" {
<       insmod part_msdos
<       insmod ntfs
<       set root='(/dev/sdb,msdos1)'
<       search --no-floppy --fs-uuid --set 5cf0b47cf0b45dc8
<       drivemap -s (hd0) ${root}
<       chainloader +1
< }
---
> #menuentry "Microsoft Windows XP Home Edition (on /dev/sdb1)" {
> #     insmod part_msdos
> #     insmod ntfs
> #     set root='(/dev/sdb,msdos1)'
> #     search --no-floppy --fs-uuid --set 5cf0b47cf0b45dc8
> #     drivemap -s (hd0) ${root}
> #     chainloader +1
> #}

Everything looks good!

As you can see, I'm being absurdly cautious. The reason?
Having my bootloader fail on me is the last thing I want
to have happen. Therefore, I'm exercising caution like
this were brain surgery.

Note that you are NOT supposed to do what I've just done:
Here's the comments at the top of grub.cfg asking
you not to do this:

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

Please understand that you make changes to your grub.cfg
file at your own risk. Honestly, I'm not asking you to change
this file. I feel a little bit out on a limb myself.

My next step is to see if I can boot my computer and that the
bootloader will work. I'm pretty confident that I'll be able
to do so as I've been very very cautious.

OK. I just rebooted the computer. The menu works perfectly!
There are now 7 menu choices instead of 8. The old copy of
Windows XP is no longer a menu choice. Success!

Update: April 16, 2012

I think I know why Grub gets updated without
me understanding why. It seems that each time
the kernel is updated, Grub gets an update too.

That'my latest theory. I just ran the following
command:

aptitude full-upgrade

Doing a full upgrade seems to have updated both
my kernel and Grub simultaneously. Are the two
updated together? Does an update of the kernel
trigger an update of Grub? Probably.

Ed Abbott

No comments:

Post a Comment