Implemented a simple Apple style partitioning scheme add-on.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4472 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ccc316dc1c
commit
0503a73f11
@ -2,3 +2,4 @@ SubDir OBOS_TOP src add-ons kernel partitioning_systems ;
|
||||
|
||||
SubInclude OBOS_TOP src add-ons kernel partitioning_systems intel ;
|
||||
SubInclude OBOS_TOP src add-ons kernel partitioning_systems amiga ;
|
||||
SubInclude OBOS_TOP src add-ons kernel partitioning_systems apple ;
|
||||
|
15
src/add-ons/kernel/partitioning_systems/apple/Jamfile
Normal file
15
src/add-ons/kernel/partitioning_systems/apple/Jamfile
Normal file
@ -0,0 +1,15 @@
|
||||
SubDir OBOS_TOP src add-ons kernel partitioning_systems apple ;
|
||||
|
||||
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName storage ] ;
|
||||
|
||||
# For now build a userland version only.
|
||||
Addon <partitioning_system>apple : userland partitioning_systems :
|
||||
apple.cpp
|
||||
;
|
||||
|
||||
LinkSharedOSLibs <partitioning_system>apple :
|
||||
libkernelland_emu.so
|
||||
libdisk_device_manager.so
|
||||
;
|
217
src/add-ons/kernel/partitioning_systems/apple/apple.cpp
Normal file
217
src/add-ons/kernel/partitioning_systems/apple/apple.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include "apple.h"
|
||||
|
||||
#include <ddm_modules.h>
|
||||
#include <KernelExport.h>
|
||||
#ifdef _BOOT_MODE
|
||||
# include <boot/partitions.h>
|
||||
#else
|
||||
# include <DiskDeviceTypes.h>
|
||||
#endif
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define TRACE_APPLE 0
|
||||
#if TRACE_APPLE
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
static const char *kPartitionModuleName = "partitioning_systems/apple/v1";
|
||||
|
||||
static const char *kApplePartitionTypes[] = {
|
||||
"partition_map", // the partition map itself
|
||||
"Driver", // contains a device driver
|
||||
"Driver43", // the SCSI 4.3 manager
|
||||
"MFS", // Macintosh File System
|
||||
"HFS", // Hierarchical File System (HFS/HFS+)
|
||||
"Unix_SVR2", // UFS
|
||||
"PRODOS",
|
||||
"Free", // unused partition
|
||||
"Scratch", // empty partition
|
||||
"Driver_ATA", // the device driver for an ATA device
|
||||
"Driver_ATAPI", // the device driver for an ATAPI device
|
||||
"Driver43_CD", // an SCSI CD-ROM driver suitable for booting
|
||||
"FWDriver", // a FireWire driver for the device
|
||||
"Void", // dummy partition map entry (used to align entries for CD-ROM)
|
||||
"Patches",
|
||||
NULL
|
||||
};
|
||||
#if 0
|
||||
static const char *kOtherPartitionTypes[] = {
|
||||
"Be_BFS", // Be's BFS (not specified endian)
|
||||
};
|
||||
#endif
|
||||
|
||||
static status_t
|
||||
get_next_partition(int fd, apple_driver_descriptor &descriptor, uint32 &cookie,
|
||||
apple_partition_map &partition)
|
||||
{
|
||||
uint32 block = cookie;
|
||||
|
||||
// find first partition map if this is the first call,
|
||||
// or else, just load the next block
|
||||
do {
|
||||
ssize_t bytesRead = read_pos(fd, (off_t)block * descriptor.BlockSize(),
|
||||
(void *)&partition, sizeof(apple_partition_map));
|
||||
if (bytesRead < (ssize_t)sizeof(apple_partition_map))
|
||||
return B_ERROR;
|
||||
|
||||
block++;
|
||||
} while (cookie == 0 && block < 64 && !partition.HasValidSignature());
|
||||
|
||||
if (!partition.HasValidSignature()) {
|
||||
if (cookie)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
// we searched for the first partition map entry and failed
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// the first partition map entry must be of type Apple_partition_map
|
||||
if (!cookie && (strncmp(partition.type, "Apple_", 6)
|
||||
|| strcmp(partition.type + 6, kApplePartitionTypes[0])))
|
||||
return B_ERROR;
|
||||
|
||||
// ToDo: warn about unknown types?
|
||||
|
||||
cookie = block;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// Apple public module interface
|
||||
|
||||
|
||||
static status_t
|
||||
apple_std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
case B_MODULE_UNINIT:
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static float
|
||||
apple_identify_partition(int fd, partition_data *partition, void **_cookie)
|
||||
{
|
||||
struct apple_driver_descriptor *descriptor;
|
||||
uint8 buffer[512];
|
||||
|
||||
if (read_pos(fd, 0, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer))
|
||||
return B_ERROR;
|
||||
|
||||
descriptor = (apple_driver_descriptor *)buffer;
|
||||
|
||||
if (!descriptor->HasValidSignature())
|
||||
return B_ERROR;
|
||||
|
||||
// ToDo: Should probably call get_next_partition() once to know if there
|
||||
// are any partitions on this disk
|
||||
|
||||
// copy the relevant part of the first block
|
||||
descriptor = new apple_driver_descriptor();
|
||||
memcpy(descriptor, buffer, sizeof(apple_driver_descriptor));
|
||||
|
||||
*_cookie = (void *)descriptor;
|
||||
|
||||
// ToDo: reevaluate the priority with ISO-9660 and others in mind
|
||||
// (for CD-ROM only, as far as I can tell)
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
apple_scan_partition(int fd, partition_data *partition, void *_cookie)
|
||||
{
|
||||
TRACE(("apple_scan_partition(cookie = %p)\n", _cookie));
|
||||
|
||||
apple_driver_descriptor &descriptor = *(apple_driver_descriptor *)_cookie;
|
||||
|
||||
partition->status = B_PARTITION_VALID;
|
||||
partition->flags |= B_PARTITION_PARTITIONING_SYSTEM
|
||||
| B_PARTITION_READ_ONLY;
|
||||
partition->content_size = descriptor.BlockSize() * descriptor.BlockCount();
|
||||
|
||||
// scan all children
|
||||
|
||||
apple_partition_map partitionMap;
|
||||
uint32 index = 0, cookie = 0;
|
||||
status_t status;
|
||||
|
||||
while ((status = get_next_partition(fd, descriptor, cookie, partitionMap)) == B_OK) {
|
||||
TRACE(("apple: found partition: name = \"%s\", type = \"%s\"\n",
|
||||
partitionMap.name, partitionMap.type));
|
||||
|
||||
if ((uint64)partition->offset + partitionMap.Start(descriptor)
|
||||
+ partitionMap.Size(descriptor) > (uint64)partition->size) {
|
||||
TRACE(("apple: child partition exceeds existing space (%Ld bytes)\n",
|
||||
partitionMap.Size(descriptor)));
|
||||
continue;
|
||||
}
|
||||
|
||||
partition_data *child = create_child_partition(partition->id, index++, -1);
|
||||
if (child == NULL) {
|
||||
TRACE(("apple: Creating child at index %ld failed\n", index - 1));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
child->offset = partition->offset + partitionMap.Start(descriptor);
|
||||
child->size = partitionMap.Size(descriptor);
|
||||
child->block_size = partition->block_size;
|
||||
}
|
||||
|
||||
if (status == B_ENTRY_NOT_FOUND)
|
||||
return B_OK;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
apple_free_identify_partition_cookie(partition_data *partition, void *_cookie)
|
||||
{
|
||||
delete (apple_driver_descriptor *)_cookie;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _BOOT_MODE
|
||||
static partition_module_info sApplePartitionModule = {
|
||||
#else
|
||||
partition_module_info gApplePartitionModule = {
|
||||
#endif
|
||||
{
|
||||
kPartitionModuleName,
|
||||
0,
|
||||
apple_std_ops
|
||||
},
|
||||
kPartitionTypeApple, // pretty_name
|
||||
0, // flags
|
||||
|
||||
// scanning
|
||||
apple_identify_partition, // identify_partition
|
||||
apple_scan_partition, // scan_partition
|
||||
apple_free_identify_partition_cookie, // free_identify_partition_cookie
|
||||
NULL,
|
||||
};
|
||||
|
||||
#ifndef _BOOT_MODE
|
||||
partition_module_info *modules[] = {
|
||||
&sApplePartitionModule,
|
||||
NULL
|
||||
};
|
||||
#endif
|
93
src/add-ons/kernel/partitioning_systems/apple/apple.h
Normal file
93
src/add-ons/kernel/partitioning_systems/apple/apple.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
#ifndef APPLE_H
|
||||
#define APPLE_H
|
||||
|
||||
|
||||
#include "SupportDefs.h"
|
||||
#include "ByteOrder.h"
|
||||
|
||||
|
||||
enum apple_signature {
|
||||
kDriverDescriptorSignature = 'ER',
|
||||
kPartitionMapSignature = 'PM',
|
||||
kObsoletePartitionMapSignature = 'TS',
|
||||
};
|
||||
|
||||
|
||||
struct apple_driver_descriptor {
|
||||
int16 signature;
|
||||
int16 block_size;
|
||||
int32 block_count;
|
||||
int16 type; // reserved
|
||||
int16 id; // "
|
||||
int32 data; // "
|
||||
int16 descriptor_count;
|
||||
int32 driver_block;
|
||||
int16 driver_size;
|
||||
int16 os_type; // operating system type
|
||||
|
||||
int16 BlockSize() { return B_BENDIAN_TO_HOST_INT16(block_size); }
|
||||
int32 BlockCount() { return B_BENDIAN_TO_HOST_INT32(block_count); }
|
||||
|
||||
bool HasValidSignature() { return B_BENDIAN_TO_HOST_INT16(signature) == kDriverDescriptorSignature; }
|
||||
};
|
||||
|
||||
struct apple_partition_map {
|
||||
int16 signature;
|
||||
int16 _reserved0;
|
||||
int32 map_block_count;
|
||||
int32 start; // in blocks
|
||||
int32 size;
|
||||
char name[32];
|
||||
char type[32];
|
||||
int32 data_start; // in blocks
|
||||
int32 data_size;
|
||||
int32 status;
|
||||
int32 boot_start;
|
||||
int32 boot_size;
|
||||
int32 boot_address;
|
||||
int32 _reserved1;
|
||||
int32 boot_entry;
|
||||
int32 _reserved2;
|
||||
int32 boot_code_checksum;
|
||||
char processor_type[16];
|
||||
|
||||
int32 StartBlock() { return B_BENDIAN_TO_HOST_INT32(start); }
|
||||
int32 BlockCount() { return B_BENDIAN_TO_HOST_INT32(size); }
|
||||
uint64 Start(apple_driver_descriptor &descriptor) { return StartBlock() * descriptor.BlockSize(); }
|
||||
uint64 Size(apple_driver_descriptor &descriptor) { return BlockCount() * descriptor.BlockSize(); }
|
||||
|
||||
bool HasValidSignature();
|
||||
};
|
||||
|
||||
|
||||
inline bool
|
||||
apple_partition_map::HasValidSignature()
|
||||
{
|
||||
int16 sig = B_BENDIAN_TO_HOST_INT16(signature);
|
||||
|
||||
return sig == kPartitionMapSignature
|
||||
|| sig == kObsoletePartitionMapSignature;
|
||||
}
|
||||
|
||||
|
||||
enum partition_status {
|
||||
kPartitionIsValid = 0x00000001,
|
||||
kPartitionIsAllocated = 0x00000002,
|
||||
kPartitionIsInUse = 0x00000004,
|
||||
kPartitionIsBootValid = 0x00000008,
|
||||
kPartitionIsReadable = 0x00000010,
|
||||
kPartitionAUXIsWriteable = 0x00000020, // dunno why IsWriteable is here twice...
|
||||
kPartitionIsBootPIC = 0x00000040,
|
||||
kPartitionIsWriteable = 0x00000020,
|
||||
kPartitionIsMounted = 0x40000000,
|
||||
kPartitionIsStartup = 0x80000000,
|
||||
kPartitionIsChainCompatible = 0x00000100,
|
||||
kPartitionIsRealDeviceDriver = 0x00000200,
|
||||
kPartitionCanChainToNext = 0x00000400,
|
||||
};
|
||||
|
||||
#endif /* APPLE_H */
|
Loading…
x
Reference in New Issue
Block a user