Check an additional special pattern to detect dangerously dedicated mode.
authorMatthew Dillon <dillon@dragonflybsd.org>
Sun, 3 Dec 2006 04:52:25 +0000 (04:52 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sun, 3 Dec 2006 04:52:25 +0000 (04:52 +0000)
Submitted-by: "Thomas E. Spanjaard" <tgen@netphreax.net>
sys/kern/subr_diskmbr.c

index 5525fd4..2618473 100644 (file)
@@ -36,7 +36,7 @@
  *     from: @(#)ufs_disksubr.c        7.16 (Berkeley) 5/4/91
  *     from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
  * $FreeBSD: src/sys/kern/subr_diskmbr.c,v 1.45 2000/01/28 10:22:07 bde Exp $
- * $DragonFly: src/sys/kern/subr_diskmbr.c,v 1.15 2006/09/10 01:26:39 dillon Exp $
+ * $DragonFly: src/sys/kern/subr_diskmbr.c,v 1.16 2006/12/03 04:52:25 dillon Exp $
  */
 
 #include <sys/param.h>
 
 static volatile u_char dsi_debug;
 
+/*
+ * This is what we have embedded in every boot1 for supporting the bogus
+ * "Dangerously Dedicated" mode. However, the old table is broken because
+ * it has an illegal geometry in it - it specifies 256 heads (heads = end
+ * head + 1) which causes nasty stuff when that wraps to zero in bios code.
+ * eg: divide by zero etc. This caused the dead-thinkpad problem, numerous
+ * SCSI bios crashes, EFI to crash, etc.
+ *
+ * We still have to recognize the old table though, even though we stopped
+ * inflicting it upon the world.
+ */
 static struct dos_partition historical_bogus_partition_table[NDOSPART] = {
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
        { 0x80, 0, 1, 0, DOSPTYP_386BSD, 255, 255, 255, 0, 50000, },
 };
+static struct dos_partition historical_bogus_partition_table_fixed[NDOSPART] = {
+       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+       { 0x80, 0, 1, 0, DOSPTYP_386BSD, 254, 255, 255, 0, 50000, },
+};
 
 static int check_part (char *sname, struct dos_partition *dp,
                           u_long offset, int nsectors, int ntracks,
@@ -102,7 +119,8 @@ check_part(char *sname, struct dos_partition *dp, u_long offset,
         * If ssector1 is on a cylinder >= 1024, then ssector can't be right.
         * Allow the C/H/S for it to be 1023/ntracks-1/nsectors, or correct
         * apart from the cylinder being reduced modulo 1024.  Always allow
-        * 1023/255/63.
+        * 1023/255/63, because this is the official way to represent
+        * pure-LBA for the starting position.
         */
        if ((ssector < ssector1
             && ((chs_ssect == nsectors && dp->dp_shd == ntracks - 1
@@ -122,7 +140,12 @@ check_part(char *sname, struct dos_partition *dp, u_long offset,
                  + mbr_offset;
        esector1 = ssector1 + dp->dp_size - 1;
 
-       /* Allow certain bogus C/H/S values for esector, as above. */
+       /*
+        * Allow certain bogus C/H/S values for esector, as above. However,
+        * heads == 255 isn't really legal and causes some BIOS crashes. The
+        * correct value to indicate a pure-LBA end is 1023/heads-1/sectors -
+        * usually 1023/254/63. "heads" is base 0, "sectors" is base 1.
+        */
        if ((esector < esector1
             && ((chs_esect == nsectors && dp->dp_ehd == ntracks - 1
                  && chs_ecyl == 1023)
@@ -220,9 +243,17 @@ reread_mbr:
        }
 
        if (bcmp(dp0, historical_bogus_partition_table,
-                sizeof historical_bogus_partition_table) == 0) {
+                sizeof historical_bogus_partition_table) == 0 ||
+           bcmp(dp0, historical_bogus_partition_table_fixed,
+                sizeof historical_bogus_partition_table_fixed) == 0) {
+#if 0
                TRACE(("%s: invalid primary partition table: historical\n",
                       sname));
+#endif /* 0 */
+               if (bootverbose)
+                       printf(
+     "%s: invalid primary partition table: Dangerously Dedicated (ignored)\n",
+                              sname);
                error = EINVAL;
                goto done;
        }