Naive partitioning system addon for Atari...

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22741 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2007-10-26 21:39:26 +00:00
parent 295059869b
commit 0e596fcaf9
3 changed files with 348 additions and 0 deletions

View File

@ -0,0 +1,18 @@
SubDir HAIKU_TOP src add-ons kernel partitioning_systems atari ;
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
UsePrivateHeaders [ FDirName kernel ] ;
UsePrivateHeaders [ FDirName storage ] ;
KernelAddon atari :
atari.cpp
;
#Addon <partitioning_system>atari :
# atari.cpp
# ;
#
#LinkAgainst <partitioning_system>atari :
# libkernelland_emu.so
# libdisk_device_manager.so
# ;

View File

@ -0,0 +1,232 @@
/*
** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include "atari.h"
#include <ByteOrder.h>
#include <KernelExport.h>
#include <ddm_modules.h>
#ifdef _BOOT_MODE
# include <boot/partitions.h>
#else
# include <DiskDeviceTypes.h>
#endif
#include <util/kernel_cpp.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#define SECTSZ 512
//#define TRACE_ATARI_PARTITION
#ifdef TRACE_ATARI_PARTITION
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
#define ATARI_PARTITION_MODULE_NAME "partitioning_systems/atari/v1"
#define ATARI_PARTITION_NAME "Atari Partition Map"
#if 0
template<typename Type> bool
validate_check_sum(Type *type)
{
if (type->SummedLongs() != sizeof(*type) / sizeof(uint32))
return false;
// check checksum
uint32 *longs = (uint32 *)type;
uint32 sum = 0;
for (uint32 i = 0; i < type->SummedLongs(); i++)
sum += B_BENDIAN_TO_HOST_INT32(longs[i]);
#ifdef TRACE_ATARI_PARTITION
if (sum != 0)
TRACE(("search_rdb: check sum is incorrect!\n"));
#endif
return sum == 0;
}
#endif
// #pragma mark -
// Atari Root Block public module interface
static status_t
atari_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
case B_MODULE_UNINIT:
return B_OK;
}
return B_ERROR;
}
static float
atari_identify_partition(int fd, partition_data *partition, void **_cookie)
{
uint8 buffer[512];
atari_root_block *arb = (atari_root_block *)buffer;
float weight = 0.5;
int i;
ssize_t bytesRead = read_pos(fd, 0, buffer, sizeof(buffer));
if (bytesRead < (ssize_t)sizeof(buffer)) {
TRACE(("%s: read error: %ld\n", __FUNCTION__, bytesRead));
return B_ERROR;
}
if (partition->offset)
return B_ERROR;
if (arb->Checksum() == 0x55aa)
weight -= 0.1; /* possible but likely a PC sector */
if (arb->_reserved_1[1] != 0x00)
weight -= 10;
/* hope so */
if (arb->MaxPartitionSize() < 10)
weight -= 20;
if ((arb->BadSectorsStart()+arb->BadSectorsCount())*(off_t)SECTSZ > partition->size)
return B_ERROR;
/* check each partition */
for (i = 0; i < 4; i++) {
struct atari_partition_entry *p = &arb->partitions[i];
if (p->Flags() & ATARI_PART_EXISTS) {
/* check for unknown flags */
if (p->Flags() & ~ (ATARI_PART_EXISTS|ATARI_PART_BOOTABLE))
weight -= 10.0;
/* id should be readable */
if (!isalnum(p->id[0]))
weight -= 1.0;
if (!isalnum(p->id[1]))
weight -= 1.0;
if (!isalnum(p->id[2]))
weight -= 1.0;
/* make sure partition doesn't overlap bad sector list */
if ((arb->BadSectorsStart() < p->Start()) &&
((arb->BadSectorsStart() + arb->BadSectorsCount()) > p->Start()))
weight -= 10;
if ((p->Start()+p->Size())*(off_t)SECTSZ > partition->size)
return B_ERROR;
/* should check partitions don't overlap each other... */
} else {
/* empty partition entry, then it must be all null */
if (p->Flags() || p->id[0] || p->id[1] || p->id[2] ||
p->Start() || p->Size())
weight -= 10.0;
else
weight += 0.1;
}
}
/* not exactly sure */
if (arb->Checksum() != ATARI_BOOTABLE_MAGIC)
weight -= 0.1;
if (weight > 1.0)
weight = 1.0;
if (weight > 0.0) {
// copy the root block to a new piece of memory
arb = new atari_root_block();
memcpy(arb, buffer, sizeof(atari_root_block));
*_cookie = (void *)arb;
return weight;
}
return B_ERROR;
}
static status_t
atari_scan_partition(int fd, partition_data *partition, void *_cookie)
{
TRACE(("atari_scan_partition(cookie = %p)\n", _cookie));
atari_root_block &arb = *(atari_root_block *)_cookie;
partition->status = B_PARTITION_VALID;
partition->flags |= B_PARTITION_PARTITIONING_SYSTEM
| B_PARTITION_READ_ONLY;
partition->content_size = partition->size;
// scan all children
uint32 index = 0;
status_t status = B_ENTRY_NOT_FOUND;
for (index = 0; index < 4; index++) {
struct atari_partition_entry *p = &arb.partitions[index];
if (!(p->Flags() & ATARI_PART_EXISTS))
continue;
TRACE(("atari: file system: %.3s\n", p->id));
if ((p->Start() + p->Size())*(uint64)SECTSZ > (uint64)partition->size) {
TRACE(("atari: child partition exceeds existing space (%Ld bytes)\n", p->Size()*SECTSZ));
continue;
}
partition_data *child = create_child_partition(partition->id, index, -1);
if (child == NULL) {
TRACE(("atari: Creating child at index %ld failed\n", index - 1));
return B_ERROR;
}
child->offset = partition->offset + p->Start() * (uint64)SECTSZ;
child->size = p->Size() * (uint64)SECTSZ;
child->block_size = SECTSZ;
status = B_OK;
}
if (status == B_ENTRY_NOT_FOUND)
return B_OK;
return status;
}
static void
atari_free_identify_partition_cookie(partition_data *partition, void *_cookie)
{
delete (atari_root_block *)_cookie;
}
#ifndef _BOOT_MODE
static partition_module_info sAtariPartitionModule = {
#else
partition_module_info gAtariPartitionModule = {
#endif
{
ATARI_PARTITION_MODULE_NAME,
0,
atari_std_ops
},
ATARI_PARTITION_NAME, // pretty_name
0, // flags
// scanning
atari_identify_partition, // identify_partition
atari_scan_partition, // scan_partition
atari_free_identify_partition_cookie, // free_identify_partition_cookie
NULL,
// atari_free_partition_cookie, // free_partition_cookie
// atari_free_partition_content_cookie, // free_partition_content_cookie
};
#ifndef _BOOT_MODE
partition_module_info *modules[] = {
&sAtariPartitionModule,
NULL
};
#endif

View File

@ -0,0 +1,98 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef ATARI_PARTITION_H
#define ATARI_PARTITION_H
#include "SupportDefs.h"
#include "ByteOrder.h"
/* this one is BIG endian */
struct atari_partition_entry {
#define ATARI_PART_EXISTS 0x01
#define ATARI_PART_BOOTABLE 0x80
uint8 flags;
char id[3]; /* "GEM", ... should use "BFS" ? */
uint32 start;
uint32 size;
uint8 Flags() const { return flags; }
uint32 Start() const { return B_BENDIAN_TO_HOST_INT32(start); }
uint32 Size() const { return B_BENDIAN_TO_HOST_INT32(size); }
} _PACKED ;
/* this one is BIG endian */
struct atari_root_block {
uint8 bootcode[0x1b6];
uint16 cylinder_count;
uint8 head_count;
uint8 _reserved_1[1];
uint16 reduced_write_current_cylinder;
uint16 write_precomp_cynlinder;
uint8 landing_zone;
uint8 seek_rate_code;
uint8 interleave_factor;
uint8 sectors_per_track;
uint32 maximum_partition_size; /* in sectors (in clusters) */
struct atari_partition_entry partitions[4];
uint32 bad_sector_list_start;
uint32 bad_sector_list_count;
#define ATARI_BOOTABLE_MAGIC 0x1234
uint16 checksum; /* checksum? 0x1234 for bootable */
uint32 MaxPartitionSize() const { return B_BENDIAN_TO_HOST_INT16(maximum_partition_size); }
uint32 BadSectorsStart() const { return B_BENDIAN_TO_HOST_INT32(bad_sector_list_start); }
uint32 BadSectorsCount() const { return B_BENDIAN_TO_HOST_INT32(bad_sector_list_count); }
uint16 Checksum() const { return B_BENDIAN_TO_HOST_INT16(checksum); }
} _PACKED ;
/************* bad blocks *************/
struct bad_block_entry {
};
struct bad_block_block {
};
/************* partition block *************/
/* this one is BIG endian, but with LITTLE endian fields! marked LE */
/* this is part of the filesystem... */
struct atari_boot_block {
uint16 branch; /* branch code */
char volume_id[6];
uint8 disk_id[3];
uint16 bytes_per_sector; /* LE */
uint8 sectors_per_cluster;
uint16 reserved_sectors; /* LE */
uint8 fat_count;
uint16 entries_in_root_dir; /* LE */
uint16 sector_count; /* LE */
uint8 media_descriptor;
uint16 sectors_per_fat; /* LE */
uint16 sectors_per_track; /* LE */
uint16 side_count; /* LE */
uint16 hidden_sector_count; /* LE */
/* boot code... */
uint16 execflag;
uint16 loadmode;
uint16 first_sector;
uint16 num_sectors;
uint32 load_addr;
uint32 fat_buffer;
/*(0x003a-0x002e)*/
#define ATARI_BB_FILENAME_SZ 0xc
char filename[ATARI_BB_FILENAME_SZ];
/*(0x01fe-0x003a)*/
#define ATARI_BB_BOOTCODE_SZ 0x1c4
uint8 bootcode[ATARI_BB_BOOTCODE_SZ];
uint16 checksum; /* 0x1234 if bootable */
};
#endif /* ATARI_PARTITION_H */