gpt: early work in progress of a disk system add-on.

* It currently allows to initialize a disk using GPT. However, this then
  fails somewhere in the kernel.
This commit is contained in:
Axel Dörfler
2013-01-23 23:16:30 +01:00
parent 3478d6ab2d
commit b44f9282b7
9 changed files with 473 additions and 0 deletions
+1
View File
@@ -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 ;
@@ -0,0 +1,155 @@
/*
* Copyright 2013, Axel Dörfler, [email protected].
* 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;
}
@@ -0,0 +1,35 @@
/*
* Copyright 2013, Axel Dörfler, [email protected].
* 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
@@ -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."
};
@@ -0,0 +1,24 @@
/*
* Copyright 2013, Axel Dörfler, [email protected].
* 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;
}
@@ -0,0 +1,155 @@
/*
* Copyright 2013, Axel Dörfler, [email protected].
* 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,0 +1,45 @@
/*
* Copyright 2013, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef GPT_PARTITION_HANDLE_H
#define GPT_PARTITION_HANDLE_H
#include <DiskSystemAddOn.h>
class GPTPartitionHandle : public BPartitionHandle {
public:
GPTPartitionHandle(
BMutablePartition* partition);
virtual ~GPTPartitionHandle();
status_t Init();
virtual uint32 SupportedOperations(uint32 mask);
virtual uint32 SupportedChildOperations(
const BMutablePartition* child,
uint32 mask);
virtual status_t GetNextSupportedType(
const BMutablePartition* child,
int32* cookie, BString* type);
virtual status_t GetPartitioningInfo(BPartitioningInfo* info);
virtual status_t GetParameterEditor(
B_PARAMETER_EDITOR_TYPE type,
BPartitionParameterEditor** editor);
virtual status_t ValidateCreateChild(off_t* offset,
off_t* size, const char* type,
BString* name, const char* parameters);
virtual status_t CreateChild(off_t offset, off_t size,
const char* type, const char* name,
const char* parameters,
BMutablePartition** child);
virtual status_t DeleteChild(BMutablePartition* child);
};
#endif // GPT_PARTITION_HANDLE_H
+17
View File
@@ -0,0 +1,17 @@
SubDir HAIKU_TOP src add-ons disk_systems gpt ;
UsePrivateHeaders shared storage ;
UsePrivateSystemHeaders ;
SEARCH_SOURCE
+= [ FDirName $(HAIKU_TOP) src add-ons kernel partitioning_systems efi ] ;
AddResources <disk_system>gpt : GPTDiskAddOn.rdef ;
Addon <disk_system>gpt :
GPTDiskSystem.cpp
GPTDiskAddOn.cpp
GPTPartitionHandle.cpp
: be $(TARGET_LIBSUPC++)
;
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright 2013, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef UTILITY_H
#define UTILITY_H
#include <SupportDefs.h>
static inline off_t
round_down(off_t a, uint32 b)
{
return a / b * b;
}
static inline off_t
round_up(off_t a, uint32 b)
{
return round_down(a + b - 1, b);
}
#endif // UTILITY_H