* 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 }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// partition_type_string
|
// partition_type_string
|
||||||
static
|
static const char *
|
||||||
const char *
|
|
||||||
partition_type_string(uint8 type)
|
partition_type_string(uint8 type)
|
||||||
{
|
{
|
||||||
int32 i;
|
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
|
// constructor
|
||||||
Partition::Partition()
|
Partition::Partition()
|
||||||
|
@ -161,21 +212,35 @@ Partition::Unset()
|
||||||
fActive = false;
|
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
|
bool
|
||||||
Partition::CheckLocation(off_t sessionSize, int32 blockSize) const
|
Partition::CheckLocation(off_t sessionSize, int32 blockSize) const
|
||||||
{
|
{
|
||||||
// offsets and size must be block aligned, PTS and partition must lie
|
// offsets and size must be block aligned, PTS and partition must lie
|
||||||
// within the session
|
// within the session
|
||||||
return (fPTSOffset % blockSize == 0
|
return fPTSOffset % blockSize == 0
|
||||||
&& fOffset % blockSize == 0
|
&& fOffset % blockSize == 0
|
||||||
&& fSize % blockSize == 0
|
&& fSize % blockSize == 0
|
||||||
&& fPTSOffset >= 0 && fPTSOffset < sessionSize
|
&& fPTSOffset >= 0 && fPTSOffset < sessionSize
|
||||||
&& fOffset >= 0 && fOffset + fSize <= sessionSize);
|
&& fOffset >= 0 && fOffset + fSize <= sessionSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// PrimaryPartition
|
// #pragma mark - PrimaryPartition
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
PrimaryPartition::PrimaryPartition()
|
PrimaryPartition::PrimaryPartition()
|
||||||
|
@ -249,7 +314,8 @@ PrimaryPartition::AddLogicalPartition(LogicalPartition *partition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// LogicalPartition
|
// #pragma mark - LogicalPartition
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
LogicalPartition::LogicalPartition()
|
LogicalPartition::LogicalPartition()
|
||||||
|
@ -295,7 +361,8 @@ LogicalPartition::Unset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// PartitionMap
|
// #pragma mark - PartitionMap
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
PartitionMap::PartitionMap()
|
PartitionMap::PartitionMap()
|
||||||
|
@ -387,59 +454,6 @@ PartitionMap::PartitionAt(int32 index) const
|
||||||
return const_cast<PartitionMap*>(this)->PartitionAt(index);
|
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
|
// Check
|
||||||
bool
|
bool
|
||||||
PartitionMap::Check(off_t sessionSize, int32 blockSize) const
|
PartitionMap::Check(off_t sessionSize, int32 blockSize) const
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
//----------------------------------------------------------------------
|
/*
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
* Copyright 2003-2006, Haiku, Inc. All Rights Reserved.
|
||||||
// by the OpenBeOS license.
|
* Distributed under the terms of the MIT License.
|
||||||
//---------------------------------------------------------------------
|
*
|
||||||
|
* Authors:
|
||||||
|
* Ingo Weinhold, bonefish@cs.tu-berlin.de
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file PartitionMap.h
|
\file PartitionMap.h
|
||||||
\brief Definitions for "intel" style partitions and interface definitions
|
\brief Definitions for "intel" style partitions and interface definitions
|
||||||
|
@ -104,6 +108,9 @@ public:
|
||||||
void SetActive(bool active) { fActive = active; }
|
void SetActive(bool active) { fActive = active; }
|
||||||
|
|
||||||
bool CheckLocation(off_t sessionSize, int32 blockSize) const;
|
bool CheckLocation(off_t sessionSize, int32 blockSize) const;
|
||||||
|
#ifdef _BOOT_MODE
|
||||||
|
void AdjustSize(off_t sessionSize);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
off_t fPTSOffset;
|
off_t fPTSOffset;
|
||||||
|
|
|
@ -88,18 +88,25 @@ PartitionMapParser::Parse(const uint8 *block, PartitionMap *map)
|
||||||
status_t
|
status_t
|
||||||
PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
|
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
|
// check the signature
|
||||||
if (error == B_OK && pts->signature != kPartitionTableSectorSignature) {
|
if (pts->signature != kPartitionTableSectorSignature) {
|
||||||
TRACE(("intel: _ParsePrimary(): invalid PTS signature\n"));
|
TRACE(("intel: _ParsePrimary(): invalid PTS signature\n"));
|
||||||
error = B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
// examine the table
|
// examine the table
|
||||||
if (error == B_OK) {
|
|
||||||
for (int32 i = 0; i < 4; i++) {
|
for (int32 i = 0; i < 4; i++) {
|
||||||
const partition_descriptor *descriptor = &pts->table[i];
|
const partition_descriptor *descriptor = &pts->table[i];
|
||||||
PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
|
PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
|
||||||
partition->SetTo(descriptor, 0, fBlockSize);
|
partition->SetTo(descriptor, 0, fBlockSize);
|
||||||
|
|
||||||
|
#ifdef _BOOT_MODE
|
||||||
|
// work-around potential BIOS problems
|
||||||
|
partition->AdjustSize(fSessionSize);
|
||||||
|
#endif
|
||||||
// ignore, if location is bad
|
// ignore, if location is bad
|
||||||
if (!partition->CheckLocation(fSessionSize, fBlockSize)) {
|
if (!partition->CheckLocation(fSessionSize, fBlockSize)) {
|
||||||
TRACE(("intel: _ParsePrimary(): partition %ld: bad location, "
|
TRACE(("intel: _ParsePrimary(): partition %ld: bad location, "
|
||||||
|
@ -107,26 +114,24 @@ PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
|
||||||
partition->Unset();
|
partition->Unset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// allocate a PTS buffer
|
// allocate a PTS buffer
|
||||||
if (error == B_OK) {
|
|
||||||
fPTS = new(nothrow) partition_table_sector;
|
fPTS = new(nothrow) partition_table_sector;
|
||||||
if (!fPTS)
|
if (fPTS == NULL)
|
||||||
error = B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
|
||||||
// parse extended partitions
|
// parse extended partitions
|
||||||
if (error == B_OK) {
|
status_t error = B_OK;
|
||||||
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
||||||
PrimaryPartition *primary = fMap->PrimaryPartitionAt(i);
|
PrimaryPartition *primary = fMap->PrimaryPartitionAt(i);
|
||||||
if (primary->IsExtended())
|
if (primary->IsExtended())
|
||||||
error = _ParseExtended(primary, primary->Offset());
|
error = _ParseExtended(primary, primary->Offset());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// cleanup
|
// cleanup
|
||||||
if (fPTS) {
|
|
||||||
delete fPTS;
|
delete fPTS;
|
||||||
fPTS = NULL;
|
fPTS = NULL;
|
||||||
}
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,6 +198,11 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
||||||
"non-extended partition allowed\n"));
|
"non-extended partition allowed\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef _BOOT_MODE
|
||||||
|
// work-around potential BIOS problems
|
||||||
|
if (partition)
|
||||||
|
partition->AdjustSize(fSessionSize);
|
||||||
|
#endif
|
||||||
// check the partition's location
|
// check the partition's location
|
||||||
if (partition && !partition->CheckLocation(fSessionSize,
|
if (partition && !partition->CheckLocation(fSessionSize,
|
||||||
fBlockSize)) {
|
fBlockSize)) {
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
// 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
|
#ifndef PARTITION_MAP_PARSER_H
|
||||||
#define PARTITION_MAP_PARSER_H
|
#define PARTITION_MAP_PARSER_H
|
||||||
|
|
||||||
|
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
class Partition;
|
class Partition;
|
||||||
class PartitionMap;
|
class PartitionMap;
|
||||||
class PrimaryPartition;
|
class PrimaryPartition;
|
||||||
struct partition_table_sector;
|
struct partition_table_sector;
|
||||||
|
|
||||||
class PartitionMapParser {
|
class PartitionMapParser {
|
||||||
public:
|
public:
|
||||||
PartitionMapParser(int deviceFD, off_t sessionOffset, off_t sessionSize,
|
PartitionMapParser(int deviceFD, off_t sessionOffset, off_t sessionSize,
|
||||||
int32 blockSize);
|
int32 blockSize);
|
||||||
~PartitionMapParser();
|
~PartitionMapParser();
|
||||||
|
@ -21,18 +28,18 @@ public:
|
||||||
int32 CountPartitions() const;
|
int32 CountPartitions() const;
|
||||||
const Partition *PartitionAt(int32 index) const;
|
const Partition *PartitionAt(int32 index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _ParsePrimary(const partition_table_sector *pts);
|
status_t _ParsePrimary(const partition_table_sector *pts);
|
||||||
status_t _ParseExtended(PrimaryPartition *primary, off_t offset);
|
status_t _ParseExtended(PrimaryPartition *primary, off_t offset);
|
||||||
status_t _ReadPTS(off_t offset, partition_table_sector *pts = NULL);
|
status_t _ReadPTS(off_t offset, partition_table_sector *pts = NULL);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fDeviceFD;
|
int fDeviceFD;
|
||||||
off_t fSessionOffset;
|
off_t fSessionOffset;
|
||||||
off_t fSessionSize;
|
off_t fSessionSize;
|
||||||
int32 fBlockSize;
|
int32 fBlockSize;
|
||||||
partition_table_sector *fPTS; // while parsing
|
partition_table_sector *fPTS; // while parsing
|
||||||
PartitionMap *fMap; //
|
PartitionMap *fMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PARTITION_MAP_PARSER_H
|
#endif // PARTITION_MAP_PARSER_H
|
||||||
|
|
Loading…
Reference in New Issue