VTserver: Installing a PDP-11 UNIX with No Tape Drive

Warren Toomey

wkt@tuhs.org

Version 2.3, March 2001

Introduction

The Vtserver program provides you with a method of copying a disk image into a PDP-11, or extracting a disk image from a PDP-11, without a tape drive or indeed an installed operating system.

The approach here is use a nearby Unix or Linux computer as both the PDP-11 console and as a virtual tape server. The VTserver software comes as two components: a set of PDP-11 software which acts as the virtual tape client, and the server which is hosted on the nearby Unix machine.

The two computers are connected via an RS-232 null modem with hardware handshaking. A KL/DL-11 unit on the PDP-11 is used as the serial port: the highest transfer rate is 9,600 bps [I could be wrong here - please let me know otherwise]. The main limitation at present is that the PDP-11 must have at least 192 Kbytes of memory.

Manifest

The VTserver software is available from ftp://minnie.tuhs.org/pub/PDP-11/Vtserver as the file
vtserver2.3x-yyyymmdd.tar.gz, where the x-yyyymmdd represents the sub-version and the date of release: it's always best to get the latest version.

When you extract the files from this tar archive, you will find directories vtserver/ and pdpvtstand/. For now, the vtserver/ directory is where you want to go, because this contains the PDP-11 binaries and the server program you need. You should have received the following files as part of the VTserver software:

vtreadme.txt:
This document in plain ASCII. There may be translations of this document in other formats, too.
vtserver.c:
The source code to the server program.
.vtrc:
The server's configuration file.
vtboot.pdp:
The machine code to bootstrap using the vtserver.
copy:
The standalone copying program.

You will also need a disk image for your PDP-11, one that is known to work for your model. If you are trying to install a UNIX, then I recommend that you use one of the available PDP-11 emulators plus the versions of UNIX in the UNIX Archive to create one of these. Don't bother trying to install a disk image unless you know that your disk image will work.

Alternatively, you may want to install 2.11BSD using the standard tape installation procedure. In this case you will also find modified versions of boot, disklabel, mkfs, icheck and restor. You will need to obtain the 2.11BSD root filesystem dump and the 2.11BSD /usr tar archives from elsewhere.

In the following section, we will discuss how to copy an existing disk image from the virtual tape server to your disk. Towards the end, there is a section on installing 2.11BSD using the standard tape installation procedure.

Compiling vtserver

The first thing to do is to compile vtserver.c:

  $ cc -o vtserver vtserver.c

The code is pretty vanilla ANSI C. The only system-specific sections are that to set the serial port to raw mode, and the use of select(). I have used the POSIX termios system calls, and you may need to modify the server code if your system isn't POSIX-compatible. Please send patches back to me for this.

Connecting the PDP-11 to the vtserver

The console KL-11 unit needs to be connected via RS-232 to a serial port on the Unix server where you compiled vtserver.c. Ok, I have no experience here as I don't have a real PDP-11. I'd strongly recommend using a null modem cable with full hardware handshaking lines (RTS/CTS and DTR/DSR) - however, I have been told that the console line doesn't support hardware handshaking. Can anybody clear this up for me?

I'd also recommend having a copy of Kermit on the Unix server end. If no communication seems to be taking place, open the serial line with Kermit, and see if characters are being received from the PDP-11. An RS-232 breakout box here could also be useful.

The .vtrc File

The file .vtrc is the server's configuration file. Lines beginning with hashes are ignored. The first (non-hashed) line gives a shell command to set the correct speed and parity of the serial line. The second line names the serial device. Remaining lines name the fictitious tape's records, and should be copy and the name of your disk image.

An example .vtrc would be:

  #       Configuration file for Virtual Tape Server
  #
  # First line is any Unix command needed to set the serial port up
  stty -f /dev/ttyid1 9600 cs8 clocal -crtscts
  #
  # Second line in this file is the serial port device
  /dev/ttyd1
  #
  # After that is the list of files on the virtual tape, e.g
  #   Record 0: the copy ptogram
  #   Record 1: a disk image for your root disk
  #
  copy
  disk.img

When the vtserver opens a file up as a tape record, it will first try to do so read/write. If this fails, it will then try to open the file read-only. And if this fails, vtserver will try to create the file. You will see messages from vtserver about how a file has been opened. The file create option allows you to name several non-existent files in the .vtrc; they can then be used as tape records to write to as required.


In your .vtrc, you will most likely need to change the name of the serial port device and the shell command to set it up. You should configure the KL-11 for 9600 baud, 8 bits, no parity, and you should do the same for the Unix server. On my FreeBSD box, the shell command in my .vtrc is:

  stty -f /dev/ttyid1 9600 cs8 clocal -crtscts

If you are using hardware handshaking lines (and you should), change this to:

  stty -f /dev/ttyid1 9600 cs8 -clocal crtscts

Starting vtserver

vtserver is started with no arguments, and reads its configuration file .vtrc. The vtserver then gives a short description of the tape's contents:

  $ vtserver
  Virtual tape server, $Revision: 1.3 $ 
  Running command stty -f /dev/ttyid1 9600 cs8 clocal -crtscts

  Tape records are:
     0 boot
     1 copy
     2 disk.img

  Opening port /dev/ttyd1 .... Port open

At this point, you can use vtserver as your PDP-11's console. However, when the VT client starts sending VT commands to vtserver, you will see messages from the server describing which file is being transferred.

As each file is opened, its name is shown on the screen. An `r' signifies a read of 512 bytes. If the VT client on the PDP-11 tries to read past the file's end, an EOF is shown. Finally, a progress message is shown every 100K of a file's download.

When not downloading a file, you can exit vtserver by typing two consecutive ESC keys at the console.

Booting via vtserver: Hand Method

The first stage of the boot process is to enter the boot code which retrieves the file boot from the vtserver. If you don't have ODT in your PDP-11, then you will have to hand-enter this code. The code should be entered at address 140000 onwards. The code is given in the file vtboot.pdp, and also in octal below.

0140000: 010706 005003 012701 177560 012704 140106 112400 100406
0140020: 105761 000004 100375 110061 000006 000770 005267 000052
0140040: 004767 000030 001403 012703 006400 005007 012702 001000
0140060: 004767 000010 110023 005302 001373 000746 105711 100376
0140100: 116100 000002 000207 025037 000000 000000 177777

Toggle in the code, and start execution at address 140000. If all goes well, the bootstrap code will start to send VT commands, and you will see the following from the vtserver:

  Opened copy read-write
   rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr EOF
  Standalone copy program - known devices are 
  ht tm ts ram hk ra rk rl rx si xp br tms vt

Booting via vtserver: ODT Method

If your PDP-11 does have ODT, then you can get the vtserver itself to send the bootstrap code down. Firstly make sure that the ODT prompt is awaiting a command, then (shutdown and) start vtserver as follows:

  $ vtserver -odt
  Virtual tape server, $Revision: 1.3 $ 
  . . .
  Opened copy read-write
   rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr EOF

The -odt flag tells vtserver to download the bootstrap code and to jump to location 140000. The first tape record is downloaded, and the standalone copy program starts up.

Note! I don't have a PDP-11 with ODT, so this feature is untested. If you have such a system, please try this out and let me know if it works. The actual code to deal with ODT in vtserver.c is relatively simple; if you find a bug, can you fix it and send me back the changes.

Copying Disk Images

When copy has loaded and starts running, you will be prompted for the input and output devices.

  Standalone copy program - known devices are 
  ht tm ts ram hk ra rk rl rx si xp br tms vt 

  Tape record n from device xx is written as xx(0,0,n)
  Disk device xx is written as xx(0,0,0)

  Enter name of input record/device:
  Enter name of output record/device:

Copy use the 2.11BSD terminology for devices, units and partitions, and you should probably read the 2.11BSD setup documentation here. However, to describe record n from tape device xx, you would say xx(0,0,n). And to describe the whole of disk device xx, you would just say xx(0,0,0).

Remember that you can read from any device and write to any device. So you can write a disk image from the vtserver to your PDP-11, or you can copy an existing disk image from your PDP-11 to a file on the vtserver.

The available tape and disk devices are:

br
RP03-like disk driver, modified to handle BR 1537 and 1711 controllers with T300, T200, T80 and T50 drives.
hk
RK06/07 disk driver.
ra
MSCP disk device driver (rx23, rx33, rx50, rd??, ra??, rz??).
rk
RK disk driver.
rl
RL disk driver.
rx
RX02 disk driver.
si
SI 9500 CDC 9766 disk driver.
xp
SMD disk driver.

vt
Virtual Tape drive.
ht
TU16/TE16/TU77 tape driver.
tm
TU10/TE10/TS03 tape driver.
ts
TS11/TU80/TS05/TK25 tape driver.

An Example Disk Image Copy

Here is an example output where the user has booted from the vtserver, loaded copy and then copied the image disk.img to their RL02 disk.

  Virtual tape server, $Revision: 1.3 $ 
  Running command stty -f /dev/ttyid1 19200 cs8 clocal -crtscts

  Tape records are:
     0 copy
     1 disk.img

  Opening port /dev/ttyd1 .... Port open

  Opened copy read-write
   rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr EOF
  Standalone copy program - known devices are 
  ht tm ts ram hk ra rk rl rx si xp br tms vt 

  Tape record n from device xx is written as xx(0,0,n)
  Disk device xx is written as xx(0,0,0)

  Enter name of input record/device: vt(0,0,1)

  Opened disk.img read-write
   Enter name of output record/device: rl(0,0,0)
  rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr ... rrrr EOF
  EOF
  Copying done. Either reset the system, or hit
  <return> to exit the standalone program.

At this point, the PDP-11 can be rebooted. If the downloaded disk image is bootable, the user should now have a working PDP-11 operating system.

Installing 2.11BSD with Vtserver

To install 2.11BSD via the vtserver, you need to set up a virtual tape with records corresponding to the standard 2.11BSD tape. You don't need any boostrap records on your virtual tape, and so your .vtrc file should look something like this (minus the comment lines):

  stty -f /dev/ttyid1 9600 cs8 clocal -crtscts
  /dev/ttyd1
  boot.dd
  disklabel
  mkfs
  restor
  icheck
  root.dump
  usr.tar
  otherusr.tar

Don't use the standalone programs disklabel, mkfs, icheck and restor from standard 2.11BSD, as they don't speak the VT protocol. Instead, use the VT-enabled programs supplied with the vtserver.

Apart from setting up the serial line, compiling and starting vtserver, and entering in the VT boot code, you should be able to follow the standard 2.11BSD installation instructions. As an example, here is an example output where a user made a root filesystem on an RL02, and then restored the root.dump to this disk:

  $ vtserver 
  Virtual tape server, $Revision: 1.3 $ 
  Running command stty -f /dev/ttyid1 19200 cs8 clocal -crtscts
  
  Tape records are:
     0 boot.dd
     1 disklabel
     2 mkfs
     3 restor
     4 icheck
     5 root.dump
  
  Opening port /dev/ttyd1 .... Port open
  
  Opened boot.dd read-write
   rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr EOF
  
  45Boot from vt(0,0,0) at 0177560
  : vt(0,0,1)
  
  Opened disklabel read-write
   rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrBoot: bootdev=06401
                                                               bootcsr=0177560
  disklabel
  Disk? rl(0,0,0)
  'rl(0,0,0)' is unlabeled or the label is corrupt.
  Proceed? [y/n] y
  d(isplay) D(efault) m(odify) w(rite) q(uit)? D
  d(isplay) D(efault) m(odify) w(rite) q(uit)? d
  
  type: old DEC
  disk: 
  label: DEFAULT
  flags:
  bytes/sector: 512
  sectors/track: 20
  tracks/cylinder: 2
  sectors/cylinder: 40
  cylinders: 512
  rpm: 3600
  drivedata: 0 0 0 0 0 
  
  1 partitions:
  #        size   offset    fstype   [fsize bsize]
    a: 20480 0  2.11BSD    1024 1024      # (Cyl. 0 - 511)
  
  d(isplay) D(efault) m(odify) w(rite) q(uit)? m
  modify
  d(isplay) g(eometry) m(isc) p(artitions) q(uit)? p
  modify partitions
  d(isplay) n(umber) s(elect) q(uit)? n
  Number of partitions (8 max) [1]? 2
  modify partitions
  d(isplay) n(umber) s(elect) q(uit)? s
  a b c d e f g h q(uit)? a
  sizes and offsets may be given as sectors, cylinders
  or cylinders plus sectors:  6200, 32c, 19c10s respectively
  modify partition 'a'
  d(isplay) z(ero) t(ype) o(ffset) s(ize) f(rag) F(size) q(uit)? s
  'a' size [20480]: 20000
  modify partition 'a'
  d(isplay) z(ero) t(ype) o(ffset) s(ize) f(rag) F(size) q(uit)? q
  modify partitions
  d(isplay) n(umber) s(elect) q(uit)? s
  a b c d e f g h q(uit)? b
  sizes and offsets may be given as sectors, cylinders
  or cylinders plus sectors:  6200, 32c, 19c10s respectively
  modify partition 'b'
  d(isplay) z(ero) t(ype) o(ffset) s(ize) f(rag) F(size) q(uit)? o
  'b' offset [0]: 20000
  modify partition 'b'
  d(isplay) z(ero) t(ype) o(ffset) s(ize) f(rag) F(size) q(uit)? s
  'b' size [0]: 480
  modify partition 'b'
  d(isplay) z(ero) t(ype) o(ffset) s(ize) f(rag) F(size) q(uit)? t
  'b' fstype [unused]: swap
  modify partition 'b'
  d(isplay) z(ero) t(ype) o(ffset) s(ize) f(rag) F(size) q(uit)? q
  modify partitions
  d(isplay) n(umber) s(elect) q(uit)? d
  
  type: old DEC
  disk: 
  label: DEFAULT
  flags:
  bytes/sector: 512
  sectors/track: 20
  tracks/cylinder: 2
  sectors/cylinder: 40
  cylinders: 512
  rpm: 3600
  drivedata: 0 0 0 0 0
  
  2 partitions:
  #        size   offset    fstype   [fsize bsize]
    a: 20000 0  2.11BSD    1024 1024      # (Cyl. 0 - 499)
    b: 480 20000  swap                    # (Cyl. 500 - 511)
  
  modify partitions
  d(isplay) n(umber) s(elect) q(uit)? q
  modify
  d(isplay) g(eometry) m(isc) p(artitions) q(uit)? q
  d(isplay) D(efault) m(odify) w(rite) q(uit)? w
  d(isplay) D(efault) m(odify) w(rite) q(uit)? q
  
  45Boot from vt(0,0,1) at 0177560
  : vt(0,0,2)
  
  Opened mkfs read-write
   rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrBoot: bootdev=06402
                                                       bootcsr=0177560
  Mkfs
  file system: rl(0,0,0)
  file sys size [10000]: 
  bytes per inode [4096]: 
  interleaving factor (m; 2 default): 
  interleaving modulus (n; 20 default): 
  isize = 2496
  m/n = 2 20
  Exit called
  
  45Boot from vt(0,0,2) at 0177560
  : vt(0,0,4)
  
  Opened icheck read-write
   rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrBoot: bootdev=06403
                                                           bootcsr=0177560
  Icheck
  File: rl(0,0,0)
  rl(0,0,0):
  files 3 (r=1,d=2,b=0,c=0,l=0,s=0)
  used 2 (i=0,ii=0,iii=0,d=2)
  free 9840
  missing 0
  
  45Boot from vt(0,0,4) at 0177560
  : vt(0,0,3)
  
  Opened restor read-write
   rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrBoot: bootdev=06404
                                                             bootcsr=0177560
  Restor
  Tape? vt(0,0,5)
  
  Opened root.dump read-write
   Disk? rl(0,0,0)
  Last chance before scribbling on disk. rrrrrrrrrrrrr ... 
  rrrrrrrrrEnd of tape
 
  45Boot from vt(0,0,4) at 0177560
  : rl(0,0,0)unix
  Boot: bootdev=03400 bootcsr=0174400
  
  2.11 BSD UNIX #115: Sat Apr 22 19:07:25 PDT 2000
      sms1@curly.2bsd.com:/usr/src/sys/GENERIC
  [etc.]

Other Comments

The vtserver/ directory holds the source code vtserver.c as well as the client binaries boot.dd, copy, disklabel, mkfs, icheck and restor.

The pdpvtstand/ directory holds the source code for the PDP-11 side of things: vtboot.pdp, boot, copy, disklabel, mkfs, icheck and restor. In fact, this is a copy of /sys/pdpstand from 2.11BSD which has been modified to have the vt.c client, the source code for copy and vtboot.pdp.

To compile all of this, you'll need a 2.11BSD system. Place this directory in /usr/src/sys, change into pdpvtstand/ and run make. See the RCS comments for details.

Caveats

The VTserver software should be considered in beta release. Your feedback is most definitely requested, to fix any bugs and to improve the software. In particular, I haven't tried this software on all PDP-11 platforms: it should work on a system without split I&D, but it does require 192 Kbytes of memory.

More specifically, I've used the Ersatz-11 2.0 demo simulator with various CPU models, and RL02 and RK05 disk images, to test copy. Here are the results: copy can read and write disk images for /24, /34A, /40, /44, /45, /70 and /94 systems when they have 256Kbytes of memory. It doesn't work for the 11/35 as it doesn't have the MUL instruction, which the 2.11BSD C compiler generates.

Also, I have never owned or used a real PDP-11. The VTserver software was developed using the Ersatz-11 2.0 simulator and Bob Supnik's 2.3 simulator. For this reason, there may be hardware-specific bugs in the software which were not found using the simulators. As well, the terminology in this manual may not be correct PDP-11 speak. Again, please send me your suggestions and improvements!


Warren Toomey
2001-03-26