Rational/R1000s400/DiskLayout

Fra DDHFwiki
Spring til navigation Spring til søgning

Rational R1000 Disk Layout

The R1K disk is split into nine slices:

  • Boot Code
  • Boot Directory
  • Volume label and Slice Table
  • DFS Superblock
  • Bad Block Table
  • Slice1 (pt. Unknown)
  • Slice2 DFS
  • Slice3 Object Store
  • Slice4 (pt. Unknown)

Despite this access seems to always be through absolute 1k sector numbers.

Boot Code

The first sector contains a short M68k20 bootloader.

The DFS directory contains an entry 'DFS_BOOTSTRAP.M200' which points to this sector.

Boot Directory

The second sector contains 9 DFS directory entries for the bootable files:

KERNEL_0.M200
KERNEL_1.M200
KERNEL_2.M200
FS_0.M200
FS_1.M200
FS_2.M200
PROGRAM_0.M200
PROGRAM_0.M200
PROGRAM_0.M200

Apart from the last four bytes, these directory entries are exact copies of the corresponding ones in the DFS filesystem.

Volume label and Slice Table

The third and fourth sectors are identical and contain the volume label including the slice table.

The following fields have been identified:

0x008-0x034 Geometry table
  Format: {16,8,8}[11]
  Units: Cylinder, Head, Sector
  512 byte sector size is used, even if
  the drive is formatted with 1k sectors.
    [0] Disk geometry (= size of volume)
    [1:2] First+Last Slice0
    [3:4] First+Last Slice1
    [5:6] First+Last Slice3
    [7:8] First+Last Slice4
    [9:10] First+Last Slice5
0x036-0x??? Disk Serial number
0x066-0x??? Volume name ("volume [12]")

DFS Superblock

The fifth sector contains the DFS "superblock"

The following fields have been identified:

0x002-0x004 First free chunk sector
0x004-0x014 Directory sectors

Bad Block Table

Duplicated sectors, entries are 32 bits:

    1 bit - 1 = Factory, 0 = Grown
   15 bits - Cylinder
    8 bits - Head
    8 bits - Sector

DFS Filesystem

  typedef uint16_t lba_t;
  
  The `superblock` is in sector four, (byteoffset 0x1000 on the disk)
  and contains:
  
      uint16_t         magic;          // == 0x7fed
      lba_t            freelist;
      lba_t            rank[8];
      xxx_t            unknown_at_14;  // copy of first free-list entry ?
  
  Each `rank` is an array of 256 sectors of 16 `dirent` slots each.
  
  A `dirent` slot is unused if the first byte is 0xff
  
  The `dirent` is 64 bytes and contains:
  
      char             filename[0x1e];
      uint16_t         hash;
      uint16_t         used_sectors;
      uint16_t         allocated_sectors;
      lba_t            first_sector;
      uint16_t         zero[10];
      uint16_t         time;           // seconds_since_midnight // 2
      uint16_t         date;           // ((YYYY - 1901) << 9) | (MM << 4) | DD
      uint16_t         unknown[1];     // Non-zero only on .M200 files
  
  Filenames can contain:
  
      $.0-9?A-Z[\]_
  
  Lower case a-z is folded to upper case.
  
  The 16 bit `hash` is calculated as:
   
      hash = sum((n+1)*(x&0x3f)**3 for n, x in enumerate(filename)) & 0xffff
  
  The `hash` determines the `rank` and `bucket` the file belongs in:
  
      rank = hash >> 13
      bucket = (hash >> 5) & 0xff
  
  The first sector of a `freelist` entry contains:
  
      uint16_t         n_sectors;
      lba_t            next_entry;
  
  The last entry in the freelist has `next_entry=0`
  
  The freelist does not seem to be sorted.