Attached is a patch which fixes proper detection of the 'new' Dangerously Dedicated MBR. Our boot1 and disklabel already supported it, but our disk mbr handling code didn't.

Cheers,
--
        Thomas E. Spanjaard
        [EMAIL PROTECTED]
diff -r c74ab86802f6 -r 698fc3960f3f sys/kern/subr_diskmbr.c
--- a/sys/kern/subr_diskmbr.c	Sat Nov 25 17:07:06 2006 +0000
+++ b/sys/kern/subr_diskmbr.c	Sat Nov 25 20:02:05 2006 +0000
@@ -35,7 +35,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 $
+ * $FreeBSD: src/sys/kern/subr_diskmbr.c,v 1.54 2001/12/11 05:35:43 peter Exp $
  * $DragonFly: src/sys/kern/subr_diskmbr.c,v 1.13 2006/04/30 17:22:17 dillon Exp $
  */
 
@@ -57,11 +57,28 @@
 
 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,
@@ -102,7 +119,8 @@ check_part(char *sname, struct dos_parti
 	 * 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_parti
 		  + 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;
 	}

Attachment: signature.asc
Description: OpenPGP digital signature



Reply via email to