Add a partitioning system for Sun disklabel/vtoc
This is the partitioning system used on sparc machines. Confirmed working with a Solaris install iso image. Added to the haiku package for sparc and to haiku_extras for other architectures. Fixes #15638 Change-Id: I0584bef5e6a66eff9a33eb6675d5533cc9a45d1e Reviewed-on: https://review.haiku-os.org/c/haiku/+/2709 Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
c1cd7f0633
commit
68ea01249e
@@ -49,7 +49,7 @@ AddFilesToPackage add-ons kernel generic
|
||||
: ata_adapter bios@x86,x86_64 dpc
|
||||
locked_pool mpu401 scsi_periph smbios@x86,x86_64 <module>tty ;
|
||||
AddFilesToPackage add-ons kernel partitioning_systems
|
||||
: amiga_rdb@m68k apple@ppc efi_gpt intel session ;
|
||||
: amiga_rdb@m68k apple@ppc sun@sparc efi_gpt intel session ;
|
||||
AddFilesToPackage add-ons kernel interrupt_controllers : openpic@ppc ;
|
||||
AddFilesToPackage add-ons kernel power cpufreq : intel_pstates@x86,x86_64 ;
|
||||
AddFilesToPackage add-ons kernel power cpuidle : intel_cstates@x86,x86_64 ;
|
||||
|
||||
@@ -5,7 +5,7 @@ HaikuPackage $(extrasPackage) ;
|
||||
|
||||
# kernel modules
|
||||
AddFilesToPackage add-ons kernel partitioning_systems
|
||||
: amiga_rdb@!m68k apple@!ppc ;
|
||||
: amiga_rdb@!m68k apple@!ppc sun@!sparc ;
|
||||
|
||||
AddFilesToPackage add-ons control_look : BeControlLook ;
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
Partitioning system for Sun Sparc machines
|
||||
==========================================
|
||||
|
||||
Infos extracted from [File System Forensic Analysis, Brian Carrier](urn:isbn:0-134-43954-6)
|
||||
and in particular the [online copy here](https://books.google.fr/books?id=Zpm9CgAAQBAJ&lpg=PT159&ots=6LIQ6blJCF&dq=solaris%20vtoc%20structure&hl=fr&pg=PT159#v=onepage&q=solaris%20vtoc%20structure&f=false), tables 6.9 and 6.10.
|
||||
|
||||
The format is called VTOC (volume table of contents). It is stored at offset 0
|
||||
on-disk. All values are big endian.
|
||||
|
||||
Note that the x86 version of Solaris uses a different layout.
|
||||
|
||||
Byte offset|Description
|
||||
0-127 |ASCII disk label
|
||||
128-261 |VTOC *
|
||||
262-263 |Sectors to skip when writing
|
||||
264-265 |Setors to skip when reading
|
||||
266-419 |Reserved
|
||||
420-421 |Disk speed
|
||||
422-423 |Number of cylinders
|
||||
424-425 |Alternates per cylinder
|
||||
426-429 |Reserved
|
||||
430-431 |Interleave
|
||||
432-433 |Number of data cylinders
|
||||
434-435 |Number of alternate cylinders
|
||||
436-437 |Number of heads
|
||||
438-439 |Number of sectors per track
|
||||
440-443 |Reserved
|
||||
444-451 |Partition 1 disk map
|
||||
... |More partition disk maps
|
||||
500-507 |Partition 8 disk map
|
||||
508-509 |Signature (0xDABE)
|
||||
510-511 |Checksum
|
||||
|
||||
The VTOC itself:
|
||||
|
||||
0-3 Version
|
||||
4-11 Volume name
|
||||
12-13 Number of partitions
|
||||
14-15 Partition 1 type
|
||||
16-17 Partition 1 flags
|
||||
... More partition types and flags
|
||||
42-45 Partition 8 type and flags
|
||||
46-57 Boot info
|
||||
58-59 Reserved
|
||||
60-63 Signature 0x600DDEEE
|
||||
64-101 Reserved
|
||||
102-105 Partition 1 timestamp
|
||||
... More partition timestamps
|
||||
130-133 Parittion 8 timestamp
|
||||
|
||||
Partition types (informative):
|
||||
|
||||
0 unassigned
|
||||
1 /boot
|
||||
2 /
|
||||
3 swap
|
||||
4 /usr
|
||||
5 entire disk
|
||||
6 /stand
|
||||
7 /var
|
||||
8 /home
|
||||
9 alternate sector
|
||||
10 cachefs
|
||||
|
||||
Partition flags:
|
||||
1 Not mountable
|
||||
128 read only
|
||||
|
||||
Disk maps:
|
||||
|
||||
0-3 Starting cylinder
|
||||
4-7 Size (in sectors)
|
||||
@@ -6,4 +6,5 @@ HaikuSubInclude atari ;
|
||||
HaikuSubInclude gpt ;
|
||||
HaikuSubInclude intel ;
|
||||
HaikuSubInclude session ;
|
||||
HaikuSubInclude sun ;
|
||||
HaikuSubInclude vmdk ;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel partitioning_systems sun ;
|
||||
|
||||
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName storage ] ;
|
||||
|
||||
KernelAddon sun :
|
||||
sun.cpp
|
||||
;
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Adrien Destugues <[email protected]>
|
||||
*
|
||||
* Distributed under terms of the MIT license.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef _BOOT_MODE
|
||||
# include <boot/partitions.h>
|
||||
#else
|
||||
# include <DiskDeviceTypes.h>
|
||||
#endif
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <ddm_modules.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
#include <KernelExport.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//#define TRACE_SUN_PARTITION
|
||||
#ifdef TRACE_SUN_PARTITION
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
#define SUN_PARTITION_MODULE_NAME "partitioning_systems/sun/v1"
|
||||
#define SUN_PARTITION_NAME "Sun volume table of contents"
|
||||
|
||||
|
||||
static uint16_t kMainSignature = 0xDABE;
|
||||
static uint32_t kVtocSignature = 0x600DDEEE;
|
||||
static uint32_t kVtocVersion = 1;
|
||||
static off_t kSectorSize = 512;
|
||||
|
||||
|
||||
struct sun_vtoc {
|
||||
char diskName[128];
|
||||
struct {
|
||||
uint32_t version;
|
||||
char volumeName[8];
|
||||
uint16_t partitionCount;
|
||||
struct {
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
} partitions[8];
|
||||
uint8_t bootinfo[12];
|
||||
uint8_t reserved[2];
|
||||
uint32_t signature;
|
||||
uint8_t reserved2[38];
|
||||
uint32_t timestamp[8];
|
||||
} __attribute__((packed)) vtoc;
|
||||
uint16_t write_skip;
|
||||
uint16_t read_skip;
|
||||
uint8_t reserved[154];
|
||||
uint16_t diskSpeed;
|
||||
uint16_t cylinders;
|
||||
uint16_t alternates;
|
||||
uint8_t reserved2[4];
|
||||
uint16_t interleave;
|
||||
uint16_t dataCylinders;
|
||||
uint16_t alternateCylinders;
|
||||
uint16_t heads;
|
||||
uint16_t sectorsPerTrack;
|
||||
uint8_t reserved3[4];
|
||||
struct {
|
||||
uint32_t startCylinder;
|
||||
uint32_t sectorCount;
|
||||
} partitions[8];
|
||||
uint16_t signature;
|
||||
uint16_t checksum;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// Sun VTOC public module interface
|
||||
|
||||
|
||||
static status_t
|
||||
sun_std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
case B_MODULE_UNINIT:
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static float
|
||||
sun_identify_partition(int fd, partition_data *partition, void **_cookie)
|
||||
{
|
||||
uint8 buffer[512];
|
||||
ssize_t bytesRead = read_pos(fd, 0, buffer, sizeof(buffer));
|
||||
sun_vtoc *vtoc = (sun_vtoc *)buffer;
|
||||
if (bytesRead < (ssize_t)sizeof(buffer)) {
|
||||
TRACE(("%s: read error: %ld\n", __FUNCTION__, bytesRead));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (vtoc->signature == B_HOST_TO_BENDIAN_INT16(kMainSignature)
|
||||
&& vtoc->vtoc.signature == B_HOST_TO_BENDIAN_INT32(kVtocSignature)
|
||||
&& vtoc->vtoc.version == B_HOST_TO_BENDIAN_INT32(kVtocVersion)) {
|
||||
// TODO verify the checksum
|
||||
|
||||
uint16_t partitionCount
|
||||
= B_BENDIAN_TO_HOST_INT16(vtoc->vtoc.partitionCount);
|
||||
TRACE(("Found %d partitions\n", partitionCount));
|
||||
|
||||
if (partitionCount > 8)
|
||||
return B_ERROR;
|
||||
|
||||
vtoc = new sun_vtoc();
|
||||
memcpy(vtoc, buffer, sizeof(sun_vtoc));
|
||||
*_cookie = (void *)vtoc;
|
||||
|
||||
bool hasParent = (get_parent_partition(partition->id) != NULL);
|
||||
if (!hasParent)
|
||||
return 0.61; // Larger than iso9660
|
||||
else
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
sun_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
{
|
||||
sun_vtoc *vtoc = (sun_vtoc *)cookie;
|
||||
|
||||
partition->status = B_PARTITION_VALID;
|
||||
partition->flags |= B_PARTITION_PARTITIONING_SYSTEM
|
||||
| B_PARTITION_READ_ONLY;
|
||||
partition->content_size = partition->size;
|
||||
|
||||
off_t headCount = B_BENDIAN_TO_HOST_INT16(vtoc->heads);
|
||||
off_t sectorsPerTrack = B_BENDIAN_TO_HOST_INT16(vtoc->sectorsPerTrack);
|
||||
off_t cylinderSize = kSectorSize * headCount * sectorsPerTrack;
|
||||
|
||||
TRACE(("%" B_PRIdOFF " heads, %" B_PRIdOFF " sectors, cylindersize %"
|
||||
B_PRIdOFF "\n", headCount, sectorsPerTrack, cylinderSize));
|
||||
|
||||
for (int i = 0; i < B_BENDIAN_TO_HOST_INT16(vtoc->vtoc.partitionCount);
|
||||
i++) {
|
||||
uint16_t type = B_BENDIAN_TO_HOST_INT16(vtoc->vtoc.partitions[i].type);
|
||||
// Ignore unused and "whole disk" entries
|
||||
if (type == 0 || type == 5)
|
||||
continue;
|
||||
|
||||
off_t start = B_BENDIAN_TO_HOST_INT32(
|
||||
vtoc->partitions[i].startCylinder) * cylinderSize;
|
||||
off_t size = B_BENDIAN_TO_HOST_INT32(vtoc->partitions[i].sectorCount)
|
||||
* kSectorSize;
|
||||
TRACE(("Part %d type %d start %" B_PRIdOFF " size %" B_PRIdOFF "\n", i,
|
||||
type, start, size));
|
||||
partition_data *child = create_child_partition(partition->id, i,
|
||||
start, size, -1);
|
||||
if (child == NULL) {
|
||||
TRACE(("sun: Creating child at index %d failed\n", i));
|
||||
return B_ERROR;
|
||||
}
|
||||
child->block_size = partition->block_size;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sun_free_identify_partition_cookie(partition_data *partition, void *_cookie)
|
||||
{
|
||||
delete (sun_vtoc *)_cookie;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _BOOT_MODE
|
||||
static partition_module_info sSunPartitionModule = {
|
||||
#else
|
||||
partition_module_info gSunPartitionModule = {
|
||||
#endif
|
||||
{
|
||||
SUN_PARTITION_MODULE_NAME,
|
||||
0,
|
||||
sun_std_ops
|
||||
},
|
||||
"sun", // short_name
|
||||
SUN_PARTITION_NAME, // pretty_name
|
||||
0, // flags
|
||||
|
||||
// scanning
|
||||
sun_identify_partition, // identify_partition
|
||||
sun_scan_partition, // scan_partition
|
||||
sun_free_identify_partition_cookie, // free_identify_partition_cookie
|
||||
NULL,
|
||||
// atari_free_partition_content_cookie, // free_partition_content_cookie
|
||||
};
|
||||
|
||||
#ifndef _BOOT_MODE
|
||||
partition_module_info *modules[] = {
|
||||
&sSunPartitionModule,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user