bugGNU GRUB - Bugs: bug #29464, util/i386/pc/grub-setup: fails to...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #29464: util/i386/pc/grub-setup: fails to write Buggy BIOS boot-sector drive-number detection in boot.img

Submitter:  TJ <intuitivenipple>
Submitted:  Wed 07 Apr 2010 09:38:10 PM UTC
   
 
Category:  Installation Severity:  Major
Priority:  5 - Normal Item Group:  Software Error
Status:  Fixed Privacy:  Public
Assigned to:  None Originator Name: 
Open/Closed:  Closed Release:  1.98
Release:  Reproducibility:  Every Time
Planned Release:  None

Wed 15 Sep 2010 01:31:19 PM UTC, comment #4: 

Fixed.

Vladimir Serbinenko <phcoder>
Group administrator
Thu 08 Apr 2010 05:02:47 PM UTC, comment #3: 

I think this patch should work a bit more neatly; it confines the mess to util/hostdisk.c and makes it emulate biosdisk more accurately.

(file #20162)

Colin Watson <cjwatson>
Group Member
Thu 08 Apr 2010 02:39:11 AM UTC, comment #2: 

After adding several debugging fprintf statements the reason for this problem seems to become clear. grub-setup calls grub_disk_open() which in turn calls an open() function via an array of pointers. Here's the source-code peppered with my debug print statements from kern/disk.c::grub_disk_open():

  grub_dprintf("disk", "grub_disk_dev_list %s\n", raw);
  for (dev = grub_disk_dev_list; dev; dev = dev->next)
    {
      grub_dprintf("disk", "dev->open (%p)\n", (void *) dev->open);
      if ((dev->open) (raw, disk) == GRUB_ERR_NONE) {
       grub_dprintf("disk", "%s\n", "GRUB_ERR_NONE");
 break;
      }
      else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) {
 grub_errno = GRUB_ERR_NONE;
       grub_dprintf("disk", "%s\n", "GRUB_ERR_UNKNOWN_DEVICE");
      }
      else
 goto fail;
    }

Running grub-setup with extra debug info output to stdout:

sudo ./grub-setup -vvv '(hd0)' >grub-setup.log 2>grub-setup.stderr.log

shows:

grub-setup: opening destination 'hd0'
/home/all/SourceCode/grub/grub2-1.98/kern/disk.c:245: Opening `hd0'...
/home/all/SourceCode/grub/grub2-1.98/kern/disk.c:268: grub_disk_dev_list hd0
/home/all/SourceCode/grub/grub2-1.98/kern/disk.c:271: dev->open (0x80754f7)
/home/all/SourceCode/grub/grub2-1.98/kern/disk.c:278: GRUB_ERR_UNKNOWN_DEVICE
/home/all/SourceCode/grub/grub2-1.98/kern/disk.c:271: dev->open (0x80740b0)
/home/all/SourceCode/grub/grub2-1.98/kern/disk.c:278: GRUB_ERR_UNKNOWN_DEVICE
/home/all/SourceCode/grub/grub2-1.98/kern/disk.c:271: dev->open (0x804b6d6)
grub_util_biosdisk_open(hd0)
find_grub_drive(hd0)
i=0 hd0
find_grub_drive(hd0) returned 0
setting disk->id=0
/home/all/SourceCode/grub/grub2-1.98/kern/disk.c:273: GRUB_ERR_NONE
grub-setup: testing: disk->id = 0

So find_grub_drive() is the function returning 0.

That function simply iterates through an array called 'map' that contains the contents of /boot/grub/device.map. The first entry in 'map' (map[0]) represents the first line in the device.map file.

From that it is now possible to see why the id is set to 0 and therefore why the buggy BIOS work-around never gets applied to the boot sector.

TJ <intuitivenipple>
Wed 07 Apr 2010 10:04:11 PM UTC, comment #1: 

* IMPORTANT *

I've noticed that the workaround gives an incorrect set of options for using dd to write to the disk. Please DO NOT use that command as it will try to truncate the output.

It should read:

4. Write the nops into the boot sector (replace /dev/sda if necessary with the boot device name on your system):

 sudo dd if=/tmp/nop.bin of=/dev/sda conv=notrunc bs=2 count=1 seek=102

TJ <intuitivenipple>
Wed 07 Apr 2010 09:38:10 PM UTC, original submission:  

I've been investigating why, on Acer Travelmate C100 tablet PCs, grub2 fails to boot, reporting:

"Geom Error"

It turns out the MBR boot sector does not have the two NOP instructions written into offset 0x66 which allows drive 0x80 to be forced as the boot device when the BIOS reports a different device - in this case 0x5F.

I traced the code in util/i386/pc/grub-setup.c and discovered that the test for the drive number fails and therefore the jmp instruction isn't over-written.

The reason is dest_dev->disk->id is never set prior to the test.

So far as I can determine this is the code-path:

utils/i386/pc/grub-setup.c::setup()
   dest_dev = grub_device_open (dest);
   kern/device.c::grub_device_open(const char *dest name)
    disk = grub_disk_open(name);
    kern/disk.c::grub_disk_open(const char *name)
      disk = (grub_disk_t) grub_zalloc(sizeof(*disk));
      disk->name = grub_strdup (name);
      ...
      disk->dev = dev;
      ...
      return disk;
   dev->disk = disk;
   return dev;
 ...
 /* If DEST_DRIVE is a hard disk, enable the workaround, which is
    for buggy BIOSes which don't pass boot drive correctly. Instead,
    they pass 0x00 or 0x01 even when booted from 0x80. */
 if (dest_dev->disk->id & 0x80)
 /* Replace the jmp (2 bytes) with double nop's. */
 *boot_drive_check = 0x9090;

To test this I added a small patch to report the value of disk->id and built the binary. When run on the target system it reveals:

./grub-setup: info: the size of hd0 is 78140160
./grub-setup: info: setting the root device to 'hd0,1'.
./grub-setup: info: disk->id = 0.

and the resulting boot sector contained the jmp instruction.

I've got a manual workaround until a fix can be created.

1. Boot from a LiveCD image from CD or network (via PXE).
2. Open a terminal (there are two ways)
 a. press Ctrl+Alt+F1 twice to get to virtual console #1
 b. Applications > Accessories > Terminal
3. Create a file containing the nops:
 echo -e -n "\0220\0220" >/tmp/nop.bin
4. Write the nops into the boot sector (replace /dev/sda if necessary with the boot device name on your system):
 sudo dd if=/tmp/nop.bin of=/dev/sda bs=2 count=1 seek=102
5. Restart and test.

This issue was originally reported in Ubuntu Forums and has a bug report against it at:

https://bugs.launchpad.net/ubuntu/+bug/555500

TJ <intuitivenipple>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attached Files
file #20162:  hostdisk-hd.diff added by cjwatson (4KiB - text/x-diff)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by phcoder (Posted a comment)
  • -email is unavailable- added by cjwatson (Updated the item)
  • -email is unavailable- added by intuitivenipple (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2010-09-15 phcoder Open/ClosedOpen Closed
    2010-09-15 phcoder StatusNone Fixed
    2010-04-08 cjwatson Attached File- Added hostdisk-hd.diff, #20162

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code