20200712

Old-school Disk Partitioning

Old-School Disk Partitions

Unix started out life in 1970. Many of the things it did, it had to invent on the fly. Disk handling was one of those items. Something we take utterly for granted today was, once upon a time, an area of active innovation. This blog will explore the early days of Unix: when we had static partitioning compiled into the driver.


Typical drive of the era: large, and difficult to manage (an RL01 or RL02 by the looks of it good for maybe 5MB or 10MB of storage).

Evolution of Partitions

Unix from the earliest days had at least two types of data that was stored on disks. The first type was a file system, which offered a hierarchical name space. The second type was swap. Unix was a swapping system from the earliest days, and to multiplex jobs into and out of memory. The kernel would keep track of what blocks were assigned to which process.

Since the disk played two different roles, with different allocation policies and persistent storage. To keep things simple, in the first edition, the disk was partitioned in a static way. The file system used its part of the disk, and swap used the rest.

DEC never did produce a partitioning standard (though later it used Unix's on its Unix-related products). This mean that the Unix guys had nothing to draw from, and so failed to produce a standard before Unix left the research group.

1st through 3rd Edition

There was almost nothing resembling partitioning in the 1st-3rd edition kernels. Unix booted off the 'drum' device using the top 64 blocks to store itself. The rest of that disk was reserved for swapping processes into/out of core memory. The sources refer to this as 'the drum' and there were 1024 256-byte blocks in the drum.

The disks were presented as a device node, which was the entire disk. This is from the 3rd edition manual page:
rk? refers to an entire RK03 disk as a single sequentially-addressed file. Its 256-word blocks are numbered 0 to 4871. Like the RF disk and the tape files, its addressing is block-oriented.
which describes a single file that has its entire block store available. The 3rd edition has the enigmatic /crp filesystem documented for one of the drives (I wonder what it's an abbreviation for):
 /dev/rk0/ filesystem 
 /dev/rk1     /usr 
 /dev/rk2/sys 
 /dev/rk3/crp 
which also shows that you had one filesystem per disk. At 1.2MB, these drives are little bigger than a floppy disk, so having just one filesystem per drive was not much of a limitation. Also note that the sector size was 256 words, or 512 bytes.

Since we have limited sources for this time period, it's hard to say for sure. The bulk of the surviving data, though, says at most the last 64 blocks are reserved for Unix...

4th Edition

With the 4th Edition, we start to see multiple files that refer to different sections of the disk. This was done because the new rp03 drives supported 81200 blocks, which exceeded the limits of the time of 65536 blocks per device. It also allows the drive to be broken up into more manageable chunks. In this release, there were 8 different files in the /dev directory named rp0 to rp7. For a second drive connected, rp8..rp15 would reference that drive. The manual has this table in it, which mirrors the surviving code:
 disk startlength 
 0 040600 
 1 4060040600 
 2 03200 
 3 320039000 
 4 4220039000 
 5-7Unassigned  
which allows basically two configurations for the drive: split in half, or split into a small root partition and two others. But where's the partition for swap?

There isn't one... Swap space in the 4th Edition was configured in param.h #defines. You defined the device, start and length on that device to use. The system would then configure that during early boot. The down side, though, of #defines was one couldn't easily do a binary patch. Swap was put in between the used parts of other of the disk. This was tricky to get right, since you had to map out the system.

You'd think that all the drives were like this, but that's not the case. The rf(4) driver specified the size of the drive itself with different minors. The rk(4) driver allowed one to experiment with different interleaf factors with different minor numbers. It really was up to the drive itself to decide how to interpret the minor number. This isn't unusual.... the various magtape drivers used minor numbers to specify density and whether or not to rewind on close.

5th and 6th Editions

The 5th edition continued the evolution. It changed the table above and there's a number of overlapping regions that need special care to be used. This also meant that you'd have to re-install the system, or hack the tables in the driver when you upgraded, if you used xp3 or xp4. There was only about 7 months between the 4th and 5th editions, so I suspect this problem wasn't too common. When 4th edition came out, there were 20 sites running it, by the 5th edition it was up to 50, so the numbers weren't huge. Since the kernel was patchable with adb or front panel switches, this issue likely could be mitigated enough to rebuild. Folks running 4th edition were trailblazers, by definition, so could be expected to cope with any upgrades they were doing to the 5th edition. By the time the 6th edition came out, it was in the hundreds or thousands, which may explain why it remained constant between 5th and 6th edition releases. The rp(4)'s predefined table became this:
 diskstartlength 
 0 040600 
40600 40600 
 29200 
 372000 9200 
 4 065535 
 5 1560065535 
 6-7Unassigned  

Swapping was still handled by using the space between the partitions or after the end of the filesystem. The 4th edition way of configuring swap was improved by moving the defines to variables that can be more easily patched with adb(1). So through the 6th edition, swap still didn't need its own partition.

What is interesting is that 5th edition introduced raw character devices as well as block devices used for filesystem.

The 6th edition uses the same tables as 5th edition. It also introduces other disk interfaces with similar hard-coded partitions using a similar scheme.

7th Edition

The 7th Edition changes the layout again. It wasn't to be mean, but was because DEC introduced newer, larger drives. 7th Edition also allows larger partitions, as disk addresses are now 3 bytes instead of two. Some drivers now support multiple drives, so the partitions are fixed, but setup so that different layouts of the devices are supported, as well as different models.  For example, the hp(4) driver supports both the rp04/rp05 and the rp06 drives (which are twice as large as the rp04/rp05 drives) so has a number of different layouts that align to this size difference so they can be used on as many different drives as possible. The hs(4) driver was also added as well, but it was more of a swap / drum device.

The problem in the PDP-11 world is that new controllers have been appearing, some from third parties, and the number of disks you can connect to the PDP-11 has started to proliferate. This problem was only going to get worse.

2BSD through 2.11BSD

Skipping ahead a bit, the 7th Edition begat 2BSD which begat a series of releases for the PDP-11 (starting amusingly enough with the 'last' PDP-11 release: 2.8BSD!). By the time we get to 2.11BSD, we have a system that has about 50 different types of disks and partitioning schemes that are increasingly difficult to manage. Each one is a special little snowflake depending on what kind of drive is attached. The table in xp the driver runs 75 lines, which the authors know is bad because they prefix this table with:
/* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
 We'll return to 2.11BSD in a part 2.

4BSD

4BSD had a similar problem. They made it more palatable by creating a program, diskpart, which displayed the default disk partitions for a specific drive type, or allowed one to create partitions tables to cut and paste into a driver and/or config files. This helped, but was still compiled into the kernel rather than on the disk pack. 4.1BSD introduced, in 1981, a new wrinkle:
 * The bad sector information and replacement sectors
 * are conventionally only accessible through the
 * 'h' file system partition of the disk.  If that
 * partition is used for a file system, the user is
 * responsible for making sure that it does not overlap
 * the bad sector information or any replacement sectors.
Progress, but it was slow. Through at least 4.3BSD this was the case: every driver had their own table that was hand-tweaked for the drives that driver supported. This was OK, as far as it went, but as the industry shifted away from controller + disk combos where there were only a few choices to standard interfaces between the drive and host and most of the functionality in the drive, this became an untenable situation.

We'll explore how it got worse, before it got better in my second part. We'll see how different vendors innovated in this area ahead of a solution that appeared in 4.3BSD Tahoe and in AT&T System Vr3.0 around the same time.

[[ edited to correct typos ]]

2 comments:

Terry Kennedy said...

The drive in the picture looks like a 5-over-5 (10MB total) model. It isn't a DEC drive as they never used 5440-type packs that way, although I believe one of the RK05 (2315-type packs) variants had fixed heads as well. An example of the 5-over-5 is the Diablo 44, but the drive in the picture is not a Diablo.

The bad sector info is defined in DEC Standard 144, which is why the Unix name for the utility to manage the bad sector table is called 'bad144'.

bsdimp2 said...

I was wondering if someone would notice or not... I made extra sure on my latest post, though, to note where the pic and the setup diverged...