* When run as part of the boot loader, it will now adjust the size of partitions
to fit into the session - this should help bug #238 to disappear. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18988 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
de20f0faca
commit
0e9f724cf8
|
@ -84,9 +84,9 @@ static const struct partition_type kPartitionTypes[] = {
|
|||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
// partition_type_string
|
||||
static
|
||||
const char *
|
||||
static const char *
|
||||
partition_type_string(uint8 type)
|
||||
{
|
||||
int32 i;
|
||||
|
@ -111,7 +111,58 @@ get_partition_type_string(uint8 type, char *buffer)
|
|||
}
|
||||
|
||||
|
||||
// Partition
|
||||
static int
|
||||
cmp_partition_offset(const void *p1, const void *p2)
|
||||
{
|
||||
const Partition *partition1 = *(const Partition**)p1;
|
||||
const Partition *partition2 = *(const Partition**)p2;
|
||||
if (partition1->Offset() < partition2->Offset())
|
||||
return -1;
|
||||
else if (partition1->Offset() > partition2->Offset())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmp_offset(const void *o1, const void *o2)
|
||||
{
|
||||
off_t offset1 = *static_cast<const off_t*>(o1);
|
||||
off_t offset2 = *static_cast<const off_t*>(o2);
|
||||
if (offset1 < offset2)
|
||||
return -1;
|
||||
else if (offset1 > offset2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
is_inside_partitions(off_t location, const Partition **partitions, int32 count)
|
||||
{
|
||||
bool result = false;
|
||||
if (count > 0) {
|
||||
// binary search
|
||||
int32 lower = 0;
|
||||
int32 upper = count - 1;
|
||||
while (lower < upper) {
|
||||
int32 mid = (lower + upper) / 2;
|
||||
const Partition *midPartition = partitions[mid];
|
||||
if (location >= midPartition->Offset() + midPartition->Size())
|
||||
lower = mid + 1;
|
||||
else
|
||||
upper = mid;
|
||||
}
|
||||
const Partition *partition = partitions[lower];
|
||||
result = (location >= partition->Offset() &&
|
||||
location < partition->Offset() + partition->Size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Partition
|
||||
|
||||
|
||||
// constructor
|
||||
Partition::Partition()
|
||||
|
@ -161,21 +212,35 @@ Partition::Unset()
|
|||
fActive = false;
|
||||
}
|
||||
|
||||
// CheckLocation
|
||||
|
||||
#ifdef _BOOT_MODE
|
||||
void
|
||||
Partition::AdjustSize(off_t sessionSize)
|
||||
{
|
||||
// To work around buggy (or older) BIOS, we shrink the partition size to
|
||||
// always fit into its session - this should improve detection of boot
|
||||
// partitions (see bug #238 for more information)
|
||||
if (sessionSize > fOffset + fSize)
|
||||
fSize = sessionSize - fOffset;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool
|
||||
Partition::CheckLocation(off_t sessionSize, int32 blockSize) const
|
||||
{
|
||||
// offsets and size must be block aligned, PTS and partition must lie
|
||||
// within the session
|
||||
return (fPTSOffset % blockSize == 0
|
||||
return fPTSOffset % blockSize == 0
|
||||
&& fOffset % blockSize == 0
|
||||
&& fSize % blockSize == 0
|
||||
&& fPTSOffset >= 0 && fPTSOffset < sessionSize
|
||||
&& fOffset >= 0 && fOffset + fSize <= sessionSize);
|
||||
&& fOffset >= 0 && fOffset + fSize <= sessionSize;
|
||||
}
|
||||
|
||||
|
||||
// PrimaryPartition
|
||||
// #pragma mark - PrimaryPartition
|
||||
|
||||
|
||||
// constructor
|
||||
PrimaryPartition::PrimaryPartition()
|
||||
|
@ -249,7 +314,8 @@ PrimaryPartition::AddLogicalPartition(LogicalPartition *partition)
|
|||
}
|
||||
|
||||
|
||||
// LogicalPartition
|
||||
// #pragma mark - LogicalPartition
|
||||
|
||||
|
||||
// constructor
|
||||
LogicalPartition::LogicalPartition()
|
||||
|
@ -295,7 +361,8 @@ LogicalPartition::Unset()
|
|||
}
|
||||
|
||||
|
||||
// PartitionMap
|
||||
// #pragma mark - PartitionMap
|
||||
|
||||
|
||||
// constructor
|
||||
PartitionMap::PartitionMap()
|
||||
|
@ -387,59 +454,6 @@ PartitionMap::PartitionAt(int32 index) const
|
|||
return const_cast<PartitionMap*>(this)->PartitionAt(index);
|
||||
}
|
||||
|
||||
// cmp_partition_offset
|
||||
static
|
||||
int
|
||||
cmp_partition_offset(const void *p1, const void *p2)
|
||||
{
|
||||
const Partition *partition1 = *(const Partition**)p1;
|
||||
const Partition *partition2 = *(const Partition**)p2;
|
||||
if (partition1->Offset() < partition2->Offset())
|
||||
return -1;
|
||||
else if (partition1->Offset() > partition2->Offset())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// cmp_offset
|
||||
static
|
||||
int
|
||||
cmp_offset(const void *o1, const void *o2)
|
||||
{
|
||||
off_t offset1 = *static_cast<const off_t*>(o1);
|
||||
off_t offset2 = *static_cast<const off_t*>(o2);
|
||||
if (offset1 < offset2)
|
||||
return -1;
|
||||
else if (offset1 > offset2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// is_inside_partitions
|
||||
static
|
||||
bool
|
||||
is_inside_partitions(off_t location, const Partition **partitions, int32 count)
|
||||
{
|
||||
bool result = false;
|
||||
if (count > 0) {
|
||||
// binary search
|
||||
int32 lower = 0;
|
||||
int32 upper = count - 1;
|
||||
while (lower < upper) {
|
||||
int32 mid = (lower + upper) / 2;
|
||||
const Partition *midPartition = partitions[mid];
|
||||
if (location >= midPartition->Offset() + midPartition->Size())
|
||||
lower = mid + 1;
|
||||
else
|
||||
upper = mid;
|
||||
}
|
||||
const Partition *partition = partitions[lower];
|
||||
result = (location >= partition->Offset() &&
|
||||
location < partition->Offset() + partition->Size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check
|
||||
bool
|
||||
PartitionMap::Check(off_t sessionSize, int32 blockSize) const
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
//----------------------------------------------------------------------
|
||||
// This software is part of the OpenBeOS distribution and is covered
|
||||
// by the OpenBeOS license.
|
||||
//---------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright 2003-2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold, bonefish@cs.tu-berlin.de
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file PartitionMap.h
|
||||
\brief Definitions for "intel" style partitions and interface definitions
|
||||
|
@ -104,6 +108,9 @@ public:
|
|||
void SetActive(bool active) { fActive = active; }
|
||||
|
||||
bool CheckLocation(off_t sessionSize, int32 blockSize) const;
|
||||
#ifdef _BOOT_MODE
|
||||
void AdjustSize(off_t sessionSize);
|
||||
#endif
|
||||
|
||||
private:
|
||||
off_t fPTSOffset;
|
||||
|
|
|
@ -88,18 +88,25 @@ PartitionMapParser::Parse(const uint8 *block, PartitionMap *map)
|
|||
status_t
|
||||
PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
|
||||
{
|
||||
status_t error = (pts ? B_OK : B_BAD_VALUE);
|
||||
if (pts == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check the signature
|
||||
if (error == B_OK && pts->signature != kPartitionTableSectorSignature) {
|
||||
if (pts->signature != kPartitionTableSectorSignature) {
|
||||
TRACE(("intel: _ParsePrimary(): invalid PTS signature\n"));
|
||||
error = B_BAD_DATA;
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
// examine the table
|
||||
if (error == B_OK) {
|
||||
for (int32 i = 0; i < 4; i++) {
|
||||
const partition_descriptor *descriptor = &pts->table[i];
|
||||
PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
|
||||
partition->SetTo(descriptor, 0, fBlockSize);
|
||||
|
||||
#ifdef _BOOT_MODE
|
||||
// work-around potential BIOS problems
|
||||
partition->AdjustSize(fSessionSize);
|
||||
#endif
|
||||
// ignore, if location is bad
|
||||
if (!partition->CheckLocation(fSessionSize, fBlockSize)) {
|
||||
TRACE(("intel: _ParsePrimary(): partition %ld: bad location, "
|
||||
|
@ -107,26 +114,24 @@ PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
|
|||
partition->Unset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// allocate a PTS buffer
|
||||
if (error == B_OK) {
|
||||
fPTS = new(nothrow) partition_table_sector;
|
||||
if (!fPTS)
|
||||
error = B_NO_MEMORY;
|
||||
}
|
||||
if (fPTS == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// parse extended partitions
|
||||
if (error == B_OK) {
|
||||
status_t error = B_OK;
|
||||
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
||||
PrimaryPartition *primary = fMap->PrimaryPartitionAt(i);
|
||||
if (primary->IsExtended())
|
||||
error = _ParseExtended(primary, primary->Offset());
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
if (fPTS) {
|
||||
delete fPTS;
|
||||
fPTS = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -193,6 +198,11 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
|||
"non-extended partition allowed\n"));
|
||||
}
|
||||
}
|
||||
#ifdef _BOOT_MODE
|
||||
// work-around potential BIOS problems
|
||||
if (partition)
|
||||
partition->AdjustSize(fSessionSize);
|
||||
#endif
|
||||
// check the partition's location
|
||||
if (partition && !partition->CheckLocation(fSessionSize,
|
||||
fBlockSize)) {
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
// PartitionMapParser.h
|
||||
|
||||
/*
|
||||
* Copyright 2003-2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold, bonefish@cs.tu-berlin.de
|
||||
*/
|
||||
#ifndef PARTITION_MAP_PARSER_H
|
||||
#define PARTITION_MAP_PARSER_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
class Partition;
|
||||
class PartitionMap;
|
||||
class PrimaryPartition;
|
||||
|
@ -32,7 +39,7 @@ private:
|
|||
off_t fSessionSize;
|
||||
int32 fBlockSize;
|
||||
partition_table_sector *fPTS; // while parsing
|
||||
PartitionMap *fMap; //
|
||||
PartitionMap *fMap;
|
||||
};
|
||||
|
||||
#endif // PARTITION_MAP_PARSER_H
|
||||
|
|
Loading…
Reference in New Issue