From 0e596fcaf9f2f72bafb4c60b6122facc768410aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 26 Oct 2007 21:39:26 +0000 Subject: [PATCH] Naive partitioning system addon for Atari... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22741 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/partitioning_systems/atari/Jamfile | 18 ++ .../partitioning_systems/atari/atari.cpp | 232 ++++++++++++++++++ .../kernel/partitioning_systems/atari/atari.h | 98 ++++++++ 3 files changed, 348 insertions(+) create mode 100644 src/add-ons/kernel/partitioning_systems/atari/Jamfile create mode 100644 src/add-ons/kernel/partitioning_systems/atari/atari.cpp create mode 100644 src/add-ons/kernel/partitioning_systems/atari/atari.h diff --git a/src/add-ons/kernel/partitioning_systems/atari/Jamfile b/src/add-ons/kernel/partitioning_systems/atari/Jamfile new file mode 100644 index 0000000000..d632767df4 --- /dev/null +++ b/src/add-ons/kernel/partitioning_systems/atari/Jamfile @@ -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 atari : +# atari.cpp +# ; +# +#LinkAgainst atari : +# libkernelland_emu.so +# libdisk_device_manager.so +# ; diff --git a/src/add-ons/kernel/partitioning_systems/atari/atari.cpp b/src/add-ons/kernel/partitioning_systems/atari/atari.cpp new file mode 100644 index 0000000000..de777b93cc --- /dev/null +++ b/src/add-ons/kernel/partitioning_systems/atari/atari.cpp @@ -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 +#include +#include +#ifdef _BOOT_MODE +# include +#else +# include +#endif +#include + +#include +#include +#include + +#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 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 + diff --git a/src/add-ons/kernel/partitioning_systems/atari/atari.h b/src/add-ons/kernel/partitioning_systems/atari/atari.h new file mode 100644 index 0000000000..ef9aa56113 --- /dev/null +++ b/src/add-ons/kernel/partitioning_systems/atari/atari.h @@ -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 */ +