Skip to content

Commit

Permalink
gpt: early work in progress of a disk system add-on.
Browse files Browse the repository at this point in the history
* It currently allows to initialize a disk using GPT. However, this then
  fails somewhere in the kernel.
  • Loading branch information
axeld committed Jan 23, 2013
1 parent 3478d6a commit b44f928
Show file tree
Hide file tree
Showing 9 changed files with 473 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/add-ons/disk_systems/Jamfile
@@ -1,5 +1,6 @@
SubDir HAIKU_TOP src add-ons disk_systems ;

SubInclude HAIKU_TOP src add-ons disk_systems bfs ;
SubInclude HAIKU_TOP src add-ons disk_systems gpt ;
SubInclude HAIKU_TOP src add-ons disk_systems intel ;
SubInclude HAIKU_TOP src add-ons disk_systems ntfs ;
155 changes: 155 additions & 0 deletions src/add-ons/disk_systems/gpt/GPTDiskAddOn.cpp
@@ -0,0 +1,155 @@
/*
* Copyright 2013, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/


#include "GPTDiskAddOn.h"

#include <new>
#include <stdio.h>

#include <DiskDeviceTypes.h>
#include <MutablePartition.h>
#include <PartitioningInfo.h>
#include <PartitionParameterEditor.h>

#include <AutoDeleter.h>
#include <disk_device_types.h>

#include "efi_gpt.h"

#include "GPTPartitionHandle.h"
#include "Utility.h"


//#define TRACE_GPT_DISK_ADD_ON
#undef TRACE
#ifdef TRACE_GPT_DISK_ADD_ON
# define TRACE(x...) printf(x)
#else
# define TRACE(x...) do {} while (false)
#endif


static const uint32 kDiskSystemFlags =
0
// | B_DISK_SYSTEM_SUPPORTS_CHECKING
// | B_DISK_SYSTEM_SUPPORTS_REPAIRING
// | B_DISK_SYSTEM_SUPPORTS_RESIZING
// | B_DISK_SYSTEM_SUPPORTS_MOVING
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS
| B_DISK_SYSTEM_SUPPORTS_INITIALIZING
// | B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME

// | B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
// | B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD
// | B_DISK_SYSTEM_SUPPORTS_SETTING_NAME
| B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE
// | B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS
| B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD
| B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD
// | B_DISK_SYSTEM_SUPPORTS_NAME
;


// #pragma mark - GPTDiskAddOn


GPTDiskAddOn::GPTDiskAddOn()
:
BDiskSystemAddOn(EFI_PARTITION_NAME, kDiskSystemFlags)
{
}


GPTDiskAddOn::~GPTDiskAddOn()
{
}


status_t
GPTDiskAddOn::CreatePartitionHandle(BMutablePartition* partition,
BPartitionHandle** _handle)
{
GPTPartitionHandle* handle
= new(std::nothrow) GPTPartitionHandle(partition);
if (handle == NULL)
return B_NO_MEMORY;

status_t error = handle->Init();
if (error != B_OK) {
delete handle;
return error;
}

*_handle = handle;
return B_OK;
}


bool
GPTDiskAddOn::CanInitialize(const BMutablePartition* partition)
{
// If it's big enough, we can initialize it.
return partition->Size() >= round_up(partition->BlockSize()
+ EFI_PARTITION_ENTRY_COUNT * EFI_PARTITION_ENTRY_SIZE,
partition->BlockSize());
}


status_t
GPTDiskAddOn::GetInitializationParameterEditor(
const BMutablePartition* partition, BPartitionParameterEditor** editor)
{
// Nothing to edit, really.
*editor = NULL;
return B_OK;
}


status_t
GPTDiskAddOn::ValidateInitialize(const BMutablePartition* partition,
BString* name, const char* parameters)
{
if (!CanInitialize(partition)
|| (parameters != NULL && parameters[0] != '\0'))
return B_BAD_VALUE;

// we don't support a content name
if (name != NULL)
name->Truncate(0);

return B_OK;
}


status_t
GPTDiskAddOn::Initialize(BMutablePartition* partition, const char* name,
const char* parameters, BPartitionHandle** _handle)
{
if (!CanInitialize(partition)
|| (name != NULL && name[0] != '\0')
|| (parameters != NULL && parameters[0] != '\0'))
return B_BAD_VALUE;

GPTPartitionHandle* handle
= new(std::nothrow) GPTPartitionHandle(partition);
if (handle == NULL)
return B_NO_MEMORY;

status_t status = partition->SetContentType(Name());
if (status != B_OK) {
delete handle;
return status;
}

partition->SetContentName(NULL);
partition->SetContentParameters(NULL);
partition->SetContentSize(
round_down(partition->Size(), partition->BlockSize()));

*_handle = handle;
return B_OK;
}
35 changes: 35 additions & 0 deletions src/add-ons/disk_systems/gpt/GPTDiskAddOn.h
@@ -0,0 +1,35 @@
/*
* Copyright 2013, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#ifndef GPT_DISK_ADD_ON_H
#define GPT_DISK_ADD_ON_H


#include <DiskSystemAddOn.h>


class GPTDiskAddOn : public BDiskSystemAddOn {
public:
GPTDiskAddOn();
virtual ~GPTDiskAddOn();

virtual status_t CreatePartitionHandle(
BMutablePartition* partition,
BPartitionHandle** handle);

virtual bool CanInitialize(
const BMutablePartition* partition);
virtual status_t GetInitializationParameterEditor(
const BMutablePartition* partition,
BPartitionParameterEditor** editor);
virtual status_t ValidateInitialize(
const BMutablePartition* partition,
BString* name, const char* parameters);
virtual status_t Initialize(BMutablePartition* partition,
const char* name, const char* parameters,
BPartitionHandle** handle);
};


#endif // GPT_DISK_ADD_ON_H
15 changes: 15 additions & 0 deletions src/add-ons/disk_systems/gpt/GPTDiskAddOn.rdef
@@ -0,0 +1,15 @@
/*
* IntelDiskAddOn.rdef
*/

resource app_signature "application/x-vnd.Haiku-IntelDiskAddOn";

resource app_version {
major = 1,
middle = 0,
minor = 0,
variety = 0,
internal = 0,
short_info = "1.0.0",
long_info = "Haiku Intel disk add-on."
};
24 changes: 24 additions & 0 deletions src/add-ons/disk_systems/gpt/GPTDiskSystem.cpp
@@ -0,0 +1,24 @@
/*
* Copyright 2013, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/


#include <new>

#include <List.h>

#include "GPTDiskAddOn.h"


status_t
get_disk_system_add_ons(BList* addOns)
{
GPTDiskAddOn* addOn = new(std::nothrow) GPTDiskAddOn();
if (!addOns->AddItem(addOn)) {
delete addOn;
return B_NO_MEMORY;
}

return B_OK;
}
155 changes: 155 additions & 0 deletions src/add-ons/disk_systems/gpt/GPTPartitionHandle.cpp
@@ -0,0 +1,155 @@
/*
* Copyright 2013, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/


#include "GPTPartitionHandle.h"

#include <new>
#include <stdio.h>

#include <DiskDeviceTypes.h>
#include <MutablePartition.h>
#include <PartitioningInfo.h>
#include <PartitionParameterEditor.h>

#include <AutoDeleter.h>

#include "gpt_known_guids.h"


//#define TRACE_GPT_PARTITION_HANDLE
#undef TRACE
#ifdef TRACE_GPT_PARTITION_HANDLE
# define TRACE(x...) printf(x)
#else
# define TRACE(x...) do {} while (false)
#endif


GPTPartitionHandle::GPTPartitionHandle(BMutablePartition* partition)
:
BPartitionHandle(partition)
{
}


GPTPartitionHandle::~GPTPartitionHandle()
{
}


status_t
GPTPartitionHandle::Init()
{
return B_OK;
}


uint32
GPTPartitionHandle::SupportedOperations(uint32 mask)
{
uint32 flags = B_DISK_SYSTEM_SUPPORTS_RESIZING
| B_DISK_SYSTEM_SUPPORTS_MOVING
| B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS
| B_DISK_SYSTEM_SUPPORTS_INITIALIZING;

// creating child
if ((mask & B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD) != 0) {
BPartitioningInfo info;
if (GetPartitioningInfo(&info) == B_OK
&& info.CountPartitionableSpaces() > 1) {
flags |= B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD;
}
}

return flags;
}


uint32
GPTPartitionHandle::SupportedChildOperations(const BMutablePartition* child,
uint32 mask)
{
return B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
| B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD
| B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE
| B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD;
}


status_t
GPTPartitionHandle::GetNextSupportedType(const BMutablePartition* child,
int32* cookie, BString* type)
{
int32 index = *cookie;
TRACE("GPTPartitionHandle::GetNextSupportedType(child: %p, cookie: %ld)\n",
child, index);

if (index >= int32(sizeof(kTypeMap) / sizeof(kTypeMap[0])))
return B_ENTRY_NOT_FOUND;

type->SetTo(kTypeMap[index].type);
*cookie = index + 1;

return B_OK;
}


status_t
GPTPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info)
{
// init to the full size (minus the first sector)
off_t size = Partition()->ContentSize();
status_t error = info->SetTo(Partition()->BlockSize(),
size - Partition()->BlockSize());
if (error != B_OK)
return error;

// TODO: exclude the space of the existing partitions

return B_OK;
}


status_t
GPTPartitionHandle::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type,
BPartitionParameterEditor** editor)
{
*editor = NULL;
if (type == B_CREATE_PARAMETER_EDITOR) {
try {
*editor = new BPartitionParameterEditor();
} catch (std::bad_alloc) {
return B_NO_MEMORY;
}
return B_OK;
}
return B_NOT_SUPPORTED;
}


status_t
GPTPartitionHandle::ValidateCreateChild(off_t* _offset, off_t* _size,
const char* typeString, BString* name, const char* parameters)
{
return B_BAD_VALUE;
}


status_t
GPTPartitionHandle::CreateChild(off_t offset, off_t size,
const char* typeString, const char* name, const char* parameters,
BMutablePartition** _child)
{
return B_BAD_VALUE;
}


status_t
GPTPartitionHandle::DeleteChild(BMutablePartition* child)
{
BMutablePartition* parent = child->Parent();
return parent->DeleteChild(child);
}

0 comments on commit b44f928

Please sign in to comment.