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:
@@ -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
|
||||
@@ -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++)
|
||||
;
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user