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:
Axel Dörfler 2003-09-03 16:28:47 +00:00
parent ccc316dc1c
commit 0503a73f11
4 changed files with 326 additions and 0 deletions

View File

@ -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 ;

View 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
;

View 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

View 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 */