Until recently I was using an MFM hard drive as the primary hard drive on my QBUS PDP-11 systems. Typically this would be an RD31 (ST-225) on an RQDX3 MSCP controller.
Over time, I am converting to using an 8GB microSDHC card as the primary hard drive. This is achieved by using a QBUS SCSI controller (either an Emulex UC07 or a CMD CQD220) connected to a V5.0a orV5.0b SCSI2SD board.
The SCSI2SD is configured using a PC-based application called “scsi2sd-util.exe”, with the SCSI2SD board connected to the PC via a USB cable.
The SCSI2SD firmware allows you to configure the SCSI2SD board to appear (on the SCSI bus) as up to 4 virtual devices. All these virtual devices are on the one microSDHC card. Each device can be a hard drive or a CDROM drive. You can’t drag-and-drop virtual hard drive files on to the microSDHC card, but you can import/export them from the card using the Linux “dd” command. When you configure the SCSI2SD card, you tell the firmware where each device starts on the microSDHC card, and the length of the device. Knowing these parameters, it is easy to use the “dd” command to import and export virtual hard drive (or CDROM) images.
The “standard” memory map that I am using for the SCSI2SD (with an 8GB microSDHC card) is as follows (the values in square brackets are for use with the “dd” command’s skip, seek and count options):
- Device DU0: Up to 256M (524,288 [or 512K] sectors, starting at sector 0 on the card)
- Device DU1: Up to 256M (524,288 [or 512K] sectors, starting at sector 524,288 [512K])
- Device DU2: Up to 2G (4,194,304 [or 4M] sectors, starting at sector 2,097,152 [2M])
- Device DU3: Up to 2G (4,194,304 [or 4M] sectors, starting at sector 6,291,456 [6M])
Note: On this webpage I am using the same convention as “dd” uses for units (ie “M” means 1024 x 1024 bytes, “MB” = 1,000,000 bytes, etc). Sectors are always 512 bytes in length.
Here are the settings I am using in scsi2sd to implement the above memory map (as at 15 October 2017):
Device 1 | Device 2 | Device 3 | Device 4 | |
---|---|---|---|---|
SCSI ID | 0 | 1 | 2 | 3 |
Device Type | Hard Drive | Hard Drive | Hard Drive | Hard Drive |
SD card start sector | 0 | 524288 [512K] | 2097152 [2M] | 6291456 [6M] |
Sector size (bytes) | 512 | 512 | 512 | 512 |
Sector count | 524288 [512K] | 524288 [512K] | 4194304 [4M] | 4194304 [4M] |
Device size | 256.00 MB | 256.00 MB | 2.00 GB | 2.00 GB |
Vendor | codesrc | codesrc | codesrc | codesrc |
Product ID | RD54 | RD54 | RA92 | RA92 |
Revision | 4.71 | 4.71 | 4.71 | 4.71 |
Serial Number | 1 | 2 | 3 | 4 |
Here is the XML configuration file that I am using for my SCSI2SD board -> scsi2sd-config-mal-20171015.xml.
Moving DU disk files between SIMH and the SCSI2SD microSDHC card
I’ve found that virtual files for DU drives in SIMH can be transferred directly to/from the microSDHC card, without the need for any manipulation. I use “WinSCP” or “FileZilla” to transfer the SIMH files from my Windows laptop (where I run SIMH) to a HP N40L Microserver (where I do most of my Linux work). I do the transfers between the Linux box and the microSDHC card using the Linux “dd” command, with the microSDHC card plugged into a USB-to-microSDHC card reader.
Before plugging the microSDHC card into the Linux box, I use the following command to list the existing hard drives and partitions that make up the Linux system:
malcolm@n40l:~$ ls -l /dev/sd* brw-rw---- 1 root disk 8, 0 Oct 15 11:58 /dev/sda brw-rw---- 1 root disk 8, 1 Oct 15 11:58 /dev/sda1 brw-rw---- 1 root disk 8, 2 Oct 15 11:58 /dev/sda2 brw-rw---- 1 root disk 8, 3 Oct 15 11:58 /dev/sda3 brw-rw---- 1 root disk 8, 5 Oct 15 11:58 /dev/sda5 brw-rw---- 1 root disk 8, 6 Oct 15 11:58 /dev/sda6 malcolm@n40l:~$
I then plug in the microSDHC card (via a USB-to-microSDHC card reader), and repeat the same command:
malcolm@n40l:~$ ls -l /dev/sd* brw-rw---- 1 root disk 8, 0 Oct 15 11:58 /dev/sda brw-rw---- 1 root disk 8, 1 Oct 15 11:58 /dev/sda1 brw-rw---- 1 root disk 8, 2 Oct 15 11:58 /dev/sda2 brw-rw---- 1 root disk 8, 3 Oct 15 11:58 /dev/sda3 brw-rw---- 1 root disk 8, 5 Oct 15 11:58 /dev/sda5 brw-rw---- 1 root disk 8, 6 Oct 15 11:58 /dev/sda6 brw-rw---- 1 root disk 8, 16 Oct 15 19:40 /dev/sdb malcolm@n40l:~$
This tells me that my microSDHC card appears as /dev/sdb.
We can now use the “dd” command to transfer individual virtual disk files (each one corresponding to a particular DU device). Extreme care needs to be taken here, as you can very easily trash your microSDHC card (or the main hard drive in your Linux system!) by any miscalculation or typo.
Some notable things about the dd command:
- “bs” is the block size. We set this to 512 bytes, as this is the standard DEC sector length
- “skip” is the number of blocks of the input file to skip past, before reading the input file
- “seek” is the number of blocks of the output file to seek past, before writing to the output file
- “count” is the maximum number of blocks to read or write
- “conv=fdatasync” ensures the data actually gets written to the SD card
IMPORTANT NOTE: Sometimes dd will work without the “conv=fdatasyn” switch, other times it will silently fail. I recommend using it all the time when reading or writing SD cards with the dd command. Without this switch, sometimes only partial data gets written to the card. You can see this by reading back from the SD card (after writing) using the dd command again, then examining the resultant file with the “xxd” command.
Writing files to the microSDHC card
For the sake of this example, let’s say we want to transfer the following virtual disk files (perhaps created in SIMH) to the microSDHC card:
- “~/Downloads/images/rtv57-sysgend.dsk” will be stored as DU0:
- “~/Downloads/images/rtv53.dsk” will be stored as DU1:
- “~/Downloads/images/saturn-mscp.dsk” will be stored as DU2:
First, let’s store “rtv57-sysgend.dsk” as DU0: (stating location is sector 0, maximum length is 512K sectors):
malcolm@n40l:~$ sudo dd if=~/Downloads/images/rtv57-sysgend.dsk of=/dev/sdb bs=512 seek=0 count=512K conv=fdatasync 41820+0 records in 41820+0 records out 21411840 bytes (21 MB) copied, 5.9549 s, 3.6 MB/s malcolm@n40l:~$
Second, let’s store “rtv53.dsk” as DU1: (starting location is sector 512K, maximum length is 512K sectors):
malcolm@n40l:~$ sudo dd if=~/Downloads/images/rtv53.dsk of=/dev/sdb bs=512 seek=512K count=512K conv=fdatasync 22272+0 records in 22272+0 records out 11403264 bytes (11 MB) copied, 3.31455 s, 3.4 MB/s malcolm@n40l:~$
Third, let’s store “/saturn-mscp.dsk” as DU2: (starting location is sector 2M, maximum length is 4M sectors):
malcolm@n40l:~$ sudo dd if=~/Downloads/images/saturn-mscp.dsk of=/dev/sdb bs=512 seek=2M count=4M conv=fdatasync 44480+0 records in 44480+0 records out 22773760 bytes (23 MB) copied, 5.50866 s, 4.1 MB/s malcolm@n40l:~$
Reading files from the microSDHC card
We can read the first hard drive from the microSD card using the following command (Note: this assumes the drive is a DEC RD31, which has 41,820 sectors):
malcolm@n40l:~$ sudo dd if=/dev/sdb of=~/Downloads/images/rtv57-sysgend.dsk bs=512 skip=0 seek=0 count=41820 conv=fdatasync 41820+0 records in 41820+0 records out 21411840 bytes (21 MB) copied, 0.941215 s, 22.7 MB/s malcolm@n40l:~$
Sector length of various DEC hard drives
Here is the assumed length of DEC hard drives (this list will grow as I work with different drives in SIMH):
- RD31 (ST-225): 41,820 sectors (615 cylinders x 4 heads x 17 sectors)
- RD54 (XT-2190): 312,120 sectors (1224 cylinders x 15 heads x 17 sectors)
Note: I’ve not been able to positively confirm the number of cylinders that the RD54 has. Perhaps the best guide is Maxtor’s Product Specification and OEM manual. The calculations shown in Section 1.2.3 of that document confirms the cylinder count (1224) and total sector count (312,120) that I have outlined above. However, when you read Section 7.1 carefully, it suggests the drive may have up to 1226 (or 1227?) cylinders of usable space. At some point I need to look carefully at the SIMH source code, to determine how many total cylinders (including any that are set aside for bad block replacements, etc) SIMH uses for the RD54.