File illumos-zfs-grub-fix-for-dell-bios of Package grub
commit 2f7f7a62d7a3e8a2e75eb88b95bc65871b6b90cb
Author: Alex Wilson <alex.wilson@joyent.com>
Date: Fri Jul 15 16:08:57 2016 -0700
5520 GRUB Error 21 booting from USB stick on Dell BIOS
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Approved by: Dan McDonald <danmcd@omniti.com>
diff --git a/usr/src/grub/grub-0.97/stage2/bios.c b/usr/src/grub/grub-0.97/stage2/bios.c
index 3203ee722d..02e92fa454 100644
--- a/usr/src/grub/grub-0.97/stage2/bios.c
+++ b/usr/src/grub/grub-0.97/stage2/bios.c
@@ -211,6 +211,7 @@ int
get_diskinfo (int drive, struct geometry *geometry)
{
int err;
+ int gotchs = 0;
/* Clear the flags. */
geometry->flags = 0;
@@ -229,6 +230,20 @@ get_diskinfo (int drive, struct geometry *geometry)
if (get_cdinfo (drive, geometry))
return 0;
}
+
+ /* Don't pass GEOMETRY directly, but pass each element instead,
+ so that we can change the structure easily. */
+ err = get_diskinfo_standard (drive,
+ &geometry->cylinders,
+ &geometry->heads,
+ &geometry->sectors);
+ if (err == 0)
+ gotchs = 1;
+ /* get_diskinfo_standard returns 0x60 if the BIOS call actually
+ succeeded but returned 0 sectors -- in this case don't
+ return yet but continue to check the LBA geom */
+ else if (err != 0x60)
+ return err;
if (version)
{
@@ -280,6 +295,30 @@ get_diskinfo (int drive, struct geometry *geometry)
/* I'm not sure if GRUB should check the bit 1 of DRP.FLAGS,
so I omit the check for now. - okuji */
/* if (drp.flags & (1 << 1)) */
+
+ /* If we didn't get valid CHS info from the standard call,
+ then we should fill it out here */
+ if (! gotchs)
+ {
+ geometry->cylinders = drp.cylinders;
+
+ if (drp.sectors > 0 && drp.heads > 0)
+ {
+ geometry->heads = drp.heads;
+ geometry->sectors = drp.sectors;
+ }
+ else
+ {
+ /* Return fake geometry. This disk reports that it
+ supports LBA, so all the other routines will use LBA
+ to talk to it and not look at this geometry. However,
+ some of the partition-finding routines still need
+ non-zero values in these fields. */
+ geometry->heads = 16;
+ geometry->sectors = 63;
+ }
+ gotchs = 1;
+ }
/* FIXME: when the 2TB limit becomes critical, we must
change the type of TOTAL_SECTORS to unsigned long
@@ -292,14 +331,10 @@ get_diskinfo (int drive, struct geometry *geometry)
}
}
- /* Don't pass GEOMETRY directly, but pass each element instead,
- so that we can change the structure easily. */
- err = get_diskinfo_standard (drive,
- &geometry->cylinders,
- &geometry->heads,
- &geometry->sectors);
- if (err)
- return err;
+ /* In case we got the 0x60 return code from _standard on a disk that
+ didn't support LBA (or was somehow invalid), return that error now */
+ if (! gotchs)
+ return 0x60;
if (! total_sectors)
{