Rational/R1000s400/DiskLayout
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 Retarget map
- Slice2 DFS
- Slice3 Object Store
- Slice4 R/W diagnostic portion
(See: Knowledge Transfer Manual pdf page 74.)
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":
0x000-0x002 | Magic number |
0x002-0x004 | First free chunk sector |
0x004-0x014 | Directory sectors |
0x014-0x400 | garbage data |
The garbage data is actually the list free-chunk sector written, because they are contiguous in the in-memory situation. (See: FS_0.M200, entrypoint 0x10390)
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 sectors only use the first 0x1de bytes. (See FS_0.M200, entry-point 0x10390) The freelist does not seem to be sorted.