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

                               Warren Toomey
                             wkt@cs.adfa.edu.au
                          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.cs.adfa.edu.au/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.4 $
  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.4 $
  . . .
  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.4 $
  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.

A Warning

Jay Jaeger sends in this timely warning about the size of disk images:

     Something I thought is worth warning folks about. For RL01, RL02,
     RK06 and RK07 (at least), the last cylinder is RESERVED for bad
     blocks and the pack serial number.

     Except for maintaining the bad block list, software should not
     write there, and should at least preserve the serial number (and
     its mirror copies that are usually present) when doing so.

     The current implementation of VTServer (in particular, the code in
     the ``hk'' driver in pdpvtstand/) does not appear to take that
     into account.

     The problem is that if you take a full pack image from a pack and
     then restore that full pack image to a different pack, you will
     wipe out the latter's bad block info (and perhaps write in some
     areas that are known not to be very good).

     Traditionally, Unix variants dealt with this by insisting that you
     use error free (Suffix -EF in the DEC part number on the pack)
     disk packs. However, if you are using real hardware you may no
     longer have those available.

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.4 $
  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-04-04
