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:
parent
295059869b
commit
0e596fcaf9
18
src/add-ons/kernel/partitioning_systems/atari/Jamfile
Normal file
18
src/add-ons/kernel/partitioning_systems/atari/Jamfile
Normal 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
|
||||
# ;
|
232
src/add-ons/kernel/partitioning_systems/atari/atari.cpp
Normal file
232
src/add-ons/kernel/partitioning_systems/atari/atari.cpp
Normal 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
|
||||
|
98
src/add-ons/kernel/partitioning_systems/atari/atari.h
Normal file
98
src/add-ons/kernel/partitioning_systems/atari/atari.h
Normal 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 */
|
||||
|
Loading…
Reference in New Issue
Block a user