diff -aur grub-0.96-orig/lib/device.c grub-0.96/lib/device.c
--- grub-0.96-orig/lib/device.c	2005-03-21 15:07:17.394333000 +0100
+++ grub-0.96/lib/device.c	2005-03-21 15:47:56.695502856 +0100
@@ -147,6 +147,8 @@
 
   /* XXX This is the default size.  */
   geom->sector_size = SECTOR_SIZE;
+  /* Use 0 to test later on if sector value has already been correctly retrieved. */
+  geom->total_sectors = 0;
   
 #if defined(__linux__)
   /* Linux */
@@ -154,17 +156,16 @@
     struct hd_geometry hdg;
     unsigned long nr;
     
+    if (! ioctl (fd, BLKGETSIZE, &nr))
+      geom->total_sectors = nr;
+    
     if (ioctl (fd, HDIO_GETGEO, &hdg))
       goto fail;
 
-    if (ioctl (fd, BLKGETSIZE, &nr))
-      goto fail;
-    
     /* Got the geometry, so save it. */
     geom->cylinders = hdg.cylinders;
     geom->heads = hdg.heads;
     geom->sectors = hdg.sectors;
-    geom->total_sectors = nr;
     
     goto success;
   }
@@ -236,9 +237,17 @@
        given a proper st_blocks size. */
     if (drive & 0x80)
       {
+       /* If a total sector count has been found and it exceeds CHS capacities,
+	* use large drive placeholder values. */
+       if (geom->total_sectors && (geom->total_sectors >= 255*63*1024)) {
+	geom->cylinders = 1024;
+	geom->heads = 255;
+	geom->sectors = 63;
+       } else {
 	geom->cylinders = DEFAULT_HD_CYLINDERS;
 	geom->heads = DEFAULT_HD_HEADS;
 	geom->sectors = DEFAULT_HD_SECTORS;
+       }
       }
     else
       {
@@ -247,11 +256,13 @@
 	geom->sectors = DEFAULT_FD_SECTORS;
       }
 
-    /* Set the total sectors properly, if we can. */
+   /* If total sectors hasn't been set yet, try and get a proper value. */
+   if (! geom->total_sectors) {
     if (! fstat (fd, &st) && st.st_blocks)
       geom->total_sectors = st.st_blocks;
     else
       geom->total_sectors = geom->cylinders * geom->heads * geom->sectors;
+   }
   }
 
  success:
