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
|
: ata_adapter bios@x86,x86_64 dpc
|
||||||
locked_pool mpu401 scsi_periph smbios@x86,x86_64 <module>tty ;
|
locked_pool mpu401 scsi_periph smbios@x86,x86_64 <module>tty ;
|
||||||
AddFilesToPackage add-ons kernel partitioning_systems
|
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 interrupt_controllers : openpic@ppc ;
|
||||||
AddFilesToPackage add-ons kernel power cpufreq : intel_pstates@x86,x86_64 ;
|
AddFilesToPackage add-ons kernel power cpufreq : intel_pstates@x86,x86_64 ;
|
||||||
AddFilesToPackage add-ons kernel power cpuidle : intel_cstates@x86,x86_64 ;
|
AddFilesToPackage add-ons kernel power cpuidle : intel_cstates@x86,x86_64 ;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ HaikuPackage $(extrasPackage) ;
|
|||||||
|
|
||||||
# kernel modules
|
# kernel modules
|
||||||
AddFilesToPackage add-ons kernel partitioning_systems
|
AddFilesToPackage add-ons kernel partitioning_systems
|
||||||
: amiga_rdb@!m68k apple@!ppc ;
|
: amiga_rdb@!m68k apple@!ppc sun@!sparc ;
|
||||||
|
|
||||||
AddFilesToPackage add-ons control_look : BeControlLook ;
|
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 gpt ;
|
||||||
HaikuSubInclude intel ;
|
HaikuSubInclude intel ;
|
||||||
HaikuSubInclude session ;
|
HaikuSubInclude session ;
|
||||||
|
HaikuSubInclude sun ;
|
||||||
HaikuSubInclude vmdk ;
|
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