MBR: Mark CHS value as invalid, not unused

As reported in #6301, some BIOSes rely on these byte to detect an unused
partition entry (set to 0) from an used one (set to some other value),
and only later notice that the CHS is invalid and LBA should be used.

Apply the patch that Ingo had attached to the ticket back then.

As far as I can tell, the protective MBR in GPT only happens to use the
same way to mark the partition as used (in case you try to plug a GPT
drive to a BIOS that does only CHS). So, using the same value should not
lead to the MBR being identified as a protective MBR by GPT aware
systems (that is detected using the partition type and partition size).

Fixes #6301.
This commit is contained in:
Adrien Destugues 2016-10-09 11:51:30 +02:00
parent 3bac309d87
commit 30cf9c3c7e
2 changed files with 10 additions and 6 deletions

View File

@ -559,8 +559,8 @@ PrimaryPartition::GetPartitionDescriptor(partition_descriptor* descriptor) const
descriptor->size = Size() / BlockSize();
descriptor->type = Type();
descriptor->active = Active() ? 0x80 : 0x00;
descriptor->begin.Unset();
descriptor->end.Unset();
descriptor->begin.SetUnused();
descriptor->end.SetUnused();
}
}
@ -713,8 +713,8 @@ LogicalPartition::GetPartitionDescriptor(partition_descriptor* descriptor,
descriptor->size = Size() / BlockSize();
descriptor->active = 0x00;
descriptor->begin.Unset();
descriptor->end.Unset();
descriptor->begin.SetUnused();
descriptor->end.SetUnused();
}

View File

@ -52,11 +52,15 @@ is_extended_type(uint8 type)
void get_partition_type_string(uint8 type, char* buffer);
// chs
// NOTE: The CHS cannot express locations within larger disks and is therefor
// mostly obsolete.
// NOTE: The CHS cannot express locations within larger disks (more than 8GB),
// and is therefore obsolete.
// However, some BIOSes still rely on it being 0 for unused partition, and some
// other value for valid records. Usually they are filled with 0xFF, which is
// an invalid CHS value, to notify the BIOS that LBA should be used instead.
struct chs {
uint8 cylinder;
uint16 head_sector; // head[15:10], sector[9:0]
void SetUnused() { cylinder = 0xFF; head_sector = 0xFFFF; }
void Unset() { cylinder = 0; head_sector = 0; }
} _PACKED;