Bug #310 » diskmbr-dd.diff
sys/kern/subr_diskmbr.c Sat Nov 25 17:07:06 2006 +0000 → sys/kern/subr_diskmbr.c Sat Nov 25 20:02:05 2006 +0000 | ||
---|---|---|
*
|
||
* 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 $
|
||
*/
|
||
... | ... | |
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,
|
||
... | ... | |
* 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
|
||
... | ... | |
+ 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)
|
||
... | ... | |
}
|
||
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;
|
||
}
|