4.3BSD Quasijarus0c
on an emulated VAX
with two NICs and routed

Version 0.03

GUIDES:
  1. 4.3BSD on SIMH
  2. NetBSD 1.3.2 (vax) on SIMH

My starting place was Gunkies Wiki. It's good. I wanted to change some things, add more explanations, and throw in networking:

This should work on a variety of Linux distributions. I tried it on CentOS 6 and Debian 8 and 9. I've done it on Raspberry pi's as well, but that gets you more the original late vax experience. A modern amd64 is much nicer and peppier.

mkdir -p ~/emulators/src ~/emulators/bin ~/emulators/4.3BSD
cd ~/emulators/src
wget -q http://simh.trailing-edge.com/sources/simhv39-0.zip
unzip simhv39-0.zip
make vax
cp BIN/vax ~/emulators/bin/
cp VAX/ka655x.bin ~/emulators/4.3BSD/
Verify ethernet support is available through a tap:

$ ~/emulators/bin/vax

MicroVAX 3900 simulator V4.0-0 Beta        git commit id: 35bfe17f
sim> show xq eth
ETH devices:
 eth0   tap:tapN                             (Integrated Tun/Tap support)
 eth1   nat:{optional-nat-parameters}        (Integrated NAT (SLiRP) support)
 eth2   udp:sourceport:remotehost:remoteport (Integrated UDP bridge support)
libpcap version 1.4.0
sim> 
Grab the 4.3BSD-Quasijarus0c.tap.bz2 from Sourceforge.

cd ~/emulators/4.3BSD
bzip2 -d 4.3BSD-Quasijarus0c.tap.bz2
Some DEC disk drives that work according to the documentation:
RA80121MB
RA81463MB
RA82622MB
RA901.2GB
RA921.5GB
All of these are supported in Quasijarus, and many more. Look through /etc/disktab on a running system.

Let's "thin-provision" a couple RA82s:

truncate -s 622M rq0-ra82.dsk
truncate -s 622M rq1-ra82.dsk
Now let's create the configuration file. I'm just going to add the second disk, which will go in /home. It's handy to have a nice partition for loading extra source (like ksh93. The bourne shell and csh just don't cut it). I'm setting up two NICs. (requiring a kernel recompile)

The OUI 08002b is actually from original DEQNA cards. You can use that or any other unicast. The physical address can be something random, but I like to embed some info in there for my reference. The second octet I use for the network, and the third for the VM on that network in order of installs.

cat > boot.conf << EOF
load -r ka655x.bin

; CPU config
set CPU 64M
set CPU conhalt
set CPU idle=all

; NVRAM
attach NVR nvram.bin

; Disk drives
set RQ0 ra82
attach RQ0 rq0-ra82.dsk
set RQ1 ra82
attach RQ1 rq1-ra82.dsk
set RQ2 dis
set RQ3 dis

; printer
attach LPT printer-output.txt

; Tape
set TQ tk50
attach tq0 4.3BSD-Quasijarus0c.tap
set TQ1 dis
set TQ2 dis
set TQ3 dis

; Disable unused peripherals
set CR dis
set RL dis
set TS dis

; Network config   : XQ:
set XQ enable
set XQ type=deqna
set XQ MAC=08-00-2b-00-00-01
attach XQ tap:tap10

set XQB enable
set XQB type=deqna
set XQB MAC=08-00-2b-00-01-01
attach XQB tap:tap11

; configure console to 7-bit only
set TTO 7b
set TTI 7b

; behavior on break
dep bdr 1

boot CPU
EOF
And add simple start script:
cat > start.sh << EOF
~/emulators/bin/vax boot.conf
EOF
chmod +x start.sh
Let's boot it. This particular section will copy a miniroot partition onto slice a of the ra82 disk, and then boot it up. Here are the commands:
boot mua0
copy
tms(0,1)
ra(0,1)
boot
ra(0,1)vmunix
ra0*
disklabel -rw ra0 ra82 bsd-disk1 /usr/mdec/rdboot /usr/mdec/bootra
disk=ra0 type=ra82 tape=tms xtr
And in context: I'll give the above in context, here:
$ ./start.sh

MicroVAX 3900 simulator V4.0-0 Beta        git commit id: 35bfe17f
install.conf-9> attach NVR nvram.bin
NVR: buffering file in memory


KA655-B V5.3, VMB 2.7
Performing normal system tests.
40..39..38..37..36..35..34..33..32..31..30..29..28..27..26..25..
24..23..22..21..20..19..18..17..16..15..14..13..12..11..10..09..
08..07..06..05..04..03..
Tests completed.
>>>boot mua0
(BOOT/R5:0 MUA0



  2..
-MUA0
  1..0..

=copy
cpu: uVAX 3000
From: tms(0,1)
To: ra(0,1)
ra0: unlabeled
Copy completed: 308 records copied
=boot
cpu: uVAX 3000

Boot
: ra(0,1)vmunix
ra0: unlabeled
326312+104440+130352 start 0x23b8
4.3 BSD Quasijarus UNIX #3: Sat Feb 14 20:31:03 PST 2004
    root@luthien.Harhan.ORG:/nbsd/usr/src/sys/GENERIC
real mem  = 67076096
SYSPTSIZE limits number of buffers to 18
avail mem = 65240064
using 18 buffers containing 147456 bytes of memory
MicroVAX 3000, ucode rev 6
tmscp0 at uba0 csr 174500 vec 774, ipl 15
tms0 at tmscp0 slave 0
uda0 at uba0 csr 172150 vec 770, ipl 15
uda0: version 3 model 3
uda0: DMA burst size set to 4
ra0 at uda0 slave 0: no disk label: no partition table for DU RA 82, size 1273856;
using (s,t,c)=(57,15,1490)
ra1 at uda0 slave 1: no disk label: no partition table for DU RA 82, size 1273856;
using (s,t,c)=(57,15,1490)
dz0 at uba0 csr 160100 vec 300, ipl 17
dz1 at uba0 csr 160110 vec 310, ipl 17
dz2 at uba0 csr 160120 vec 320, ipl 17
dz3 at uba0 csr 160130 vec 330, ipl 17
root device? ra0*
WARNING: clock lost 114 days -- CHECK AND RESET THE DATE!
#
Much faster than the old days.

Now, we'll label the disk (disklabel is the partitioner, using data in /etc/disktab) and run xtr (a shell script in / that extracts the miniroot from tape and runs fsck on the filesystem).

# disklabel -rw ra0 ra82 bsd-disk1 /usr/mdec/rdboot /usr/mdec/bootra
# disk=ra0 type=ra82 tape=tms xtr
Build root file system
Warning: 361 sector(s) in last cylinder unallocated
/dev/rra0a:     15884 sectors in 19 cylinders of 15 tracks, 57 sectors
        8.1MB in 2 cyl groups (16 c/g, 7.00MB/g, 3200 i/g)
super-block backups (for fsck -b #) at:
 32, 13776,
Check the file system
** /dev/rra0a
** Last Mounted on 
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
1 files, 1 used, 7092 free (20 frags, 884 blocks, 0.3% fragmentation)
Rewind tape
Restore the dump image of the root
** /dev/rra0a
** Last Mounted on /a
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
426 files, 5195 used, 1898 free (18 frags, 235 blocks, 0.3% fragmentation)
Root filesystem extracted

If this is an 8650 or 8600, update the console rl02
If this is a 780 or 785, update the floppy
If this is a 730, update the cassette
# 
We need to reboot, to get a more full set of utilities. Now sync it (just to make sure) and "power it off" by hitting ctrl-E and typing "exit".

# sync;sync;sync
Simulation stopped, PC: 800029AF (BNEQ 800029C6)
sim> exit
Goodbye
NVR: writing buffer to file
Ok, let's go ahead and configure the bridge and taps. See RedHat documentation for making them permanent in /etc/sysconfig/network-scripts. The numbers are arbitrary--I've got other things I don't want it to interfere with. Do this as root: I'm leaving spanning tree off, because I'm not connecting these to any physical switches, and they're separated internally at layer 3. You can enable it later if you connect this to a physical nic that's on another switch, or if you do something complicated with switches.

brctl addbr br10
ifconfig br10 192.168.100.1/24
ifconfig br10 up
brctl addbr br11
ifconfig br11 192.168.101.1/24
ifconfig br11 up
tunctl -t tap10 -u agarvin
tunctl -t tap11 -u agarvin
brctl addif br10 tap10
brctl addif br11 tap11
ifconfig tap10 up
ifconfig tap11 up
Let's get the rest of the OS setup. We'll remove the nvram so we can switch the boot device at startup. What we'll type in is as follows:
rm -f nvram.bin
./start.sh

VAX simulator V3.9-0
NVR: buffering file in memory
LPT: creating new file
TQ: creating new file
libpcap version 1.4.0
Eth: opened OS device tap10
Eth: opened OS device tap11

Performing normal system tests.
40..39..38..37..36..35..34..33..32..31..30..29..28..27..26..25..
24..23..22..21..20..19..18..17..16..15..14..13..12..11..10..09..
08..07..06..05..04..03..
Tests completed.
Loading system software.
No default boot device has been specified.

Available devices.
-DUA0 (RA82)
-DUA1 (RA82)
-MUA0 (TK50)
-XQA0 (08-00-2B-00-00-01)
-XQB0 (08-00-2B-00-01-01)

Device? [XQA0]: dua0

(BOOT/R5:0 DUA0



  2..
-DUA0
  1..0..

loading boot

Boot
: /vmunix
326312+104440+130352 start 0x23b8
4.3 BSD Quasijarus UNIX #3: Sat Feb 14 20:31:03 PST 2004
    root@luthien.Harhan.ORG:/nbsd/usr/src/sys/GENERIC
real mem  = 67076096
SYSPTSIZE limits number of buffers to 18
avail mem = 65240064
using 18 buffers containing 147456 bytes of memory
MicroVAX 3000, ucode rev 6
tmscp0 at uba0 csr 174500 vec 774, ipl 15
tms0 at tmscp0 slave 0
uda0 at uba0 csr 172150 vec 770, ipl 15
uda0: version 3 model 3
uda0: DMA burst size set to 4
ra0 at uda0 slave 0: ra82, size = 1216665 sectors
ra1 at uda0 slave 1: no disk label: ra82, size = 1216665 sectors
dz0 at uba0 csr 160100 vec 300, ipl 17
dz1 at uba0 csr 160110 vec 310, ipl 17
dz2 at uba0 csr 160120 vec 320, ipl 17
dz3 at uba0 csr 160130 vec 330, ipl 17
lp0 at uba0 csr 177514 vec 200, ipl 17
qe0 at uba0 csr 174440 vec 764, ipl 14
qe0: deqna, hardware address 08:00:2b:00:00:01
Changing root device to ra0a
Automatic reboot in progress...
Thu Oct 23 15:14:20 PDT 2003
Can't open checklist file: /etc/fstab
Automatic reboot failed... help!
erase ^?, kill ^U, intr ^C
#
I'll just give the commands here. I recommend pasting them one (or typing them) at a time instead of as a block. The console doesn't seem to accept pastes very well on my system (once you get telnet or rsh up, it's better)
newfs ra0g ra82
newfs ra0h ra82
cd /etc
cat > fstab << EOF
/dev/ra0a:/:rw:1:1
/dev/ra0g:/usr:rw:1:2
/dev/ra0h:/usr/local:rw:1:3
/dev/ra1c:/home:rw:1:4
EOF
mount /usr
cd /dev
./MAKEDEV tmscp0
cd /usr
mt rew
mt fsf 3
tar xvpb 20
mkdir src
cd src
mkdir sys
cd sys
mt rew
mt fsf 4
tar xvpb 20
cd ..
mt rew
mt fsf 5
tar xvpb 20
VERY fast compared to those ancient DLTs or QICs of the era.

We can add the second disk now. Slice c is the entire disk, which you may remember from Solaris (still the case? I haven't installed Solaris since 8). The dz0 makedev will create tty devices, so you don't get annoying messages on the console, and pty0 will get you pseudo ttys for telneting or rsh'ing in.

cd /dev
./MAKEDEV ra1 dz0 pty0
disklabel -rw ra1 ra82 bsd-disk2
newfs ra1c ra82
mkdir /home
mount /home
Here's what df should look like:
# df
Filesystem    kbytes    used   avail capacity  Mounted on
/dev/ra0a       7093    5199    1184    81%    /
/dev/ra0g     394851   71681  283684    20%    /usr
/dev/ra0h     136504       1  122852     0%    
/dev/ra1c     571290       1  514160     0%    /home
That's it! This is a pristine system install, and where I want to make a backup. Shut it down:
# shutdown -h now
Shutdown at 15:41 (in 0 minutes) [pid 94]
# 
System shutdown time has arrived
syncing disks... done

?06 HLT INST
        PC = 8002F4C2
>>>
Simulation stopped, PC: 20043601 (BSBW 2004367B)
sim> exit
Goodbye
NVR: writing buffer to file
Eth: closed tap10
Eth: closed tap11
Here's a good small backup:
[4.3BSD]$ cd ..
[emulators]$ mkdir 4.3-pristine-install
[emulators]$ rsync -av --sparse 4.3BSD/ 4.3-pristine-install
sending incremental file list
./
4.3BSD-Quasijarus0c.tap
boot.conf
ka655x.bin
nvram.bin
printer-output.txt
rq0-ra82.dsk
rq1-ra82.dsk
start.sh

sent 1389182977 bytes  received 205 bytes  185224424.27 bytes/sec
total size is 1389012727  speedup is 1.00

Boot it back up again with ./start.sh, and we can configure things.

I like to use the editor 'ex', which is like a line-buffered vi with no full-screen edit mode. It's better than ed. Use 'a' to add a line after your current line, 'i' to insert before, '.' on a new line to exit insert mode, and otherwise, everything is pretty much like the : mode in vi. To make ex your preferred editor, add this to your .profile:

EDITOR=/usr/ucb/ex
export EDITOR
The vi editor just doesn't work well at the console or with non-standard window sizes.

Let's clean some stuff up:

Get rid of this annoying line in the crontab /usr/lib/crontab:

1,11,21,31,41,51 * * * *        root    (echo -n '      '; date; echo -n ^M) >/dev/console
It prints the date to the console every 10 minutes, as a primitive screen saver.

Edit /etc/hosts, /etc/networks and /etc/netstart. Mine are below:

# cat /etc/hosts
127.0.0.1 localhost localhost.my.domain
192.168.100.10 bsd1 bsd1.nitfol.local
192.168.101.10 bsd1-in bsd1-in.nitfol.local
# grep my- /etc/networks
my-net 192.168.100
my-net-in 192.168.101
my-netmask 255.255.255
# cat /etc/netstart
#!/bin/sh -
#
#       @(#)netstart    1.1 (Berkeley) 1/10/99

routedflags=-q
rwhod=YES

hostname=bsd1.nitfol.local
hostname $hostname

ifconfig qe0 inet $hostname netmask my-netmask
ifconfig qe1 inet bsd1-in netmask my-netmask

ifconfig lo0  inet localhost
route add $hostname localhost 0
hostid $hostname
We won't get the qe1 interface until we recompile the kernel. Let's do that now. cd to /sys/conf, and add this line in GENERIC:
device          qe1     at uba? csr 0174460     vector qeintr
Make sure it's placed below qe0, or the default network setup will be screwy.

Then run:

# config GENERIC
Don't forget to run "make depend"
Change into /usr/src/sys/GENERIC
make clean
make depend
make
cp /vmunix /vmunix.orig
cp vmunix /vmunix
Now reboot with 'shutdown -h now'. When you reboot, try:

# netstat -i
Name  Mtu   Network     Address            Ipkts Ierrs    Opkts Oerrs  Coll
qe0   1500  my-net      bsd1                   1     0        3     0     0
qe1   1500  my-net-in   bsd1-in                1     0        1     0     0
lo0   1536  loopback-ne localhost            137     0      137     0     0
"Interesting" thing is 4.2BSD automatically starts routed. This caused many fun problems on campuses when someone brought up a new install and screwed up the whole routing table, especially if they played with metrics. In 4.3 they changed it to have a -q flag, so it wouldn't broadcast info. If you install multiple boxes with routed, you'll want to start it with -s so it'll broadcast out its route info.

One note on Debian: rsh and rcp are symlinks to ssh and scp, annoyingly. There's a lot of things like that in Debian that annoy me. You can install rsh-client which gets you binaries named netkit-rsh and netkit-rcp that are handy. There's also good old telnet. Setting your term to vt320 works reasonably well.

Things to do now, in rough order of difficulty and/or fun:

  1. Add a user for yourself, with su privileges.
  2. Get ksh93 from the ATT Software Github and compile it (requires a little work), so you can have a reasonable shell. Go to groups.google.com, get traceroute which was posted every so often on Usenet (or write your own! hint: it uses UDP packets with an incrementing TTL and looks at the return ICMP). Try early GNU utils.
  3. Add more hosts, on both sides of the network. Configure the routes so they can ping each other. Add sendmail support.
  4. Add more networks, explore RIP. Trigger a count to infinity. See what a routing loop looks like. (use wireshark on the bridges and taps to learn more)
  5. Replicate the Morris Worm of '88 on your network! Melt those VMs down!
  6. Get a copy of Stevens' TCP/IP illustrated, Vol 1 (1st edition only!!), set up a similar network, work through all the examples. You might want to emulate an old Cisco router with GNS3.
  7. Get a copy of Stevens' TCP/IP illustrated, Vol 2 and learn the 4.3BSD TCP/IP stack in detail (it's actually based on Lite-2, but this is close enough)
  8. Get a copy of The Design and Implementation of the 4.3 BSD Operating System and learn all the internals. There's also a rarer problems book in paperback, with exercises to work through.
  9. Make your own 4.4BSD by ripping out all the ATT internals and recoding them yourself. (Or your own hybrid by adding SysV system calls). Add flags to commands, and extend things to look more like modern Unixes. Like Minix, it's trivial to extend things yourself, because everything is so simple and, well, kinda primitive.

Mail me at aurvondel@gmail.com with corrections or suggestions.