Have you ever wanted to run some ancient Unix on original hardware? Well, the hardware is hardly accessible nowadays, but fortunately, we have SimH, the simulator for historical computers.

In this post, we’ll briefly boot up Unix v5 on a PDP11 and see how it looks and feels like.

I’ve chosen a PDP11 on purpose, because that was the machine that Unix was written on.

Obtaining and installing SimH

Just use your favorite packaging system to install simh on your Unix system. Alternatively, fetch simh, compile and install it the usual way. On FreeBSD, using the emulators/simh port, we get the following binaries:

$ ls -ltc /usr/local/bin | head -n28
 
-r-xr-xr-x    1 root  wheel     734088 May  5 15:40 altairz80
-r-xr-xr-x    1 root  wheel     175600 May  5 15:40 gri
-r-xr-xr-x    1 root  wheel     207552 May  5 15:40 h316
-r-xr-xr-x    1 root  wheel     425472 May  5 15:40 hp2100
-r-xr-xr-x    1 root  wheel     198624 May  5 15:40 i1401
-r-xr-xr-x    1 root  wheel     205072 May  5 15:40 i1620
-r-xr-xr-x    1 root  wheel     325512 May  5 15:40 i7094
-r-xr-xr-x    1 root  wheel     240048 May  5 15:40 ibm1130
-r-xr-xr-x    1 root  wheel     244168 May  5 15:40 id16
-r-xr-xr-x    1 root  wheel     252360 May  5 15:40 id32
-r-xr-xr-x    1 root  wheel     167920 May  5 15:40 lgp
-r-xr-xr-x    1 root  wheel     211752 May  5 15:40 nova
-r-xr-xr-x    1 root  wheel     221104 May  5 15:40 pdp1
-r-xr-xr-x    1 root  wheel     361992 May  5 15:40 pdp10
-r-xr-xr-x    1 root  wheel     656160 May  5 15:40 pdp11
-r-xr-xr-x    1 root  wheel     264456 May  5 15:40 pdp15
-r-xr-xr-x    1 root  wheel     244968 May  5 15:40 pdp4
-r-xr-xr-x    1 root  wheel     249800 May  5 15:40 pdp7
-r-xr-xr-x    1 root  wheel     285968 May  5 15:40 pdp8
-r-xr-xr-x    1 root  wheel     255624 May  5 15:40 pdp9
-r-xr-xr-x    1 root  wheel     188440 May  5 15:40 s3
-r-xr-xr-x    1 root  wheel     242536 May  5 15:40 sds
-r-xr-xr-x    1 root  wheel     340840 May  5 15:40 simh-eclipse
-r-xr-xr-x    1 root  wheel     204448 May  5 15:40 swtp6800mp-a
-r-xr-xr-x    1 root  wheel     204712 May  5 15:40 swtp6800mp-a2
-r-xr-xr-x    1 root  wheel     556872 May  5 15:40 vax
-r-xr-xr-x    1 root  wheel     630088 May  5 15:40 vax780
-r-xr-xr-x    1 root  wheel     180192 May  5 15:40 altair

Obtaining Unix v5

The SimH Software Kits page provides a copy of Unix v5 (and v6 and v7) for PDP11, courtesy of Caldera. Fetch that file and save it somwhere.

Now, create a directory somewhere, cd into it, and unpack uv5swre.zip.

$ ls -l
 
-rwxr-xr-x  1 farid  users    12299 Jan 24  2002 AncientUnix.pdf
-rwxr-xr-x  1 farid  users      263 Nov 25  1996 README.txt
-rw-r--r--  1 farid  users       48 May  5 16:57 pdp11.ini
-rwxr-xr-x  1 farid  users  2494464 May  5 17:48 unix_v5_rk.dsk
 
$ cat pdp11.ini
set cpu U18
attach rk0 unix_v5_rk.dsk
boot rk0

You’ll need to create the file pdp11.ini yourself though.

Running the PDP11 simulator

Now we’re all set to start the PDP11 simulator. At the @-prompt, just type the name of the kernel: unix, followed by Enter:

$ pdp11
 
PDP-11 simulator V3.9-0
Disabling XQ
@unix
 
;login: root
#

Unix v5 boots very fast, and doesn’t show any boot message. At the login-prompt, just log in as root. No password is required.

Looking around Unix v5

Let’s look around a little. Note that this is a simple shell, nothing fancy like bash, ksh and so on. You can’t use the backspace key (it won’t work). Furthermore, and pretty annoying, you need to use chdir instead of cd to change directory. Fortunately, ls works as expected, including its -l switch.

So what’s in the root directory?
# ls -l /
total 60
drwxr-xr-x  2 bin       944 Nov 26 18:13 bin
drwxr-xr-x  2 bin        80 Nov 26 18:13 dev
drwxr-xr-x  2 bin       240 Mar 21 12:07 etc
drwxr-xr-x  2 bin       224 Nov 26 18:13 lib
drwxr-xr-x  2 bin        32 Nov 26 18:13 mnt
drwxrwxrwx  2 bin       160 Mar 21 12:15 tmp
-rwxrwxrwx  1 bin     25802 Mar 21 12:07 unix
drwxr-xr-x 14 bin       224 Nov 26 18:13 usr

See how tiny the kernel unix really is? That’s a far stretch from the overbloated Unix/Linux/BSD/Solaris/… kernels of today. A truly minimalistic system.

What’s in /dev?

Not that much, really. Just a /dev/mem device for the whole memory, the /dev/null device, and a terminal device /dev/tty8 that happens to be our console:

# ls -l /dev
total 0
cr--r--r--  1 bin     1,  0 Nov 26 18:13 mem
crw-rw-rw-  1 bin     1,  2 Nov 26 18:13 null
crw--w--w-  1 root    0,  0 Mar 21 12:39 tty8
 
# tty
tty8
And /etc?

A look into /etc may be interesting too:

# ls -l /etc
total 38
-rwxr--r--  1 bin       474 Nov 26 18:13 getty
-rwxr-xr-x  1 bin      1446 Nov 26 18:13 glob
-rwxr--r--  1 bin      1972 Nov 26 18:13 init
-rwxr-xr-x  1 bin       814 Nov 26 18:13 lpd
-rwxr--r--  1 bin      4136 Nov 26 18:13 mkfs
-rwxr--r--  1 bin      1800 Nov 26 18:13 mknod
-rwsr-xr-x  1 root     2078 Nov 26 18:13 mount
-rw-r--r--  1 bin        49 Nov 26 18:13 passwd
-rw-r--r--  1 bin        70 Nov 26 18:13 rc
-rw-r--r--  1 bin        56 Nov 26 18:13 ttys
-rwsr-xr-x  1 root     1990 Nov 26 18:13 umount
-rwxr-xr-x  1 bin        32 Nov 26 18:13 update
-rw-r--r--  1 root      144 Mar 21 12:16 utmp
 
# cat /etc/rc
rm -f /etc/mtab
chdir /tmp
rm -f [a-t]* [x-z]* v*
chdir /
/etc/update

There are a couple of programs that didn’t fit elsewhere, esp. administrative commands like mkfs, mount and so on.

The /etc/rc startup code just cleans up tmp, and resets the mounted filesystems file /etc/mtab. Oh, cat works too, of course.

Show me all thy commands

The real interesting part is, of course, /bin

# chdir /bin
# ls -l
total 336
-rwxr-xr-x  1 bin      1514 Nov 26 18:13 ar
-rwxr-xr-x  1 bin      7308 Nov 26 18:13 as
-rwxr-xr-x  1 bin      6042 Nov 26 18:13 bas
-rwxr-xr-x  1 bin       152 Nov 26 18:13 cat
-rwxr-xr-x  1 bin      5668 Nov 26 18:13 cc
-rwxr-xr-x  1 bin      4338 Nov 26 18:13 cdb
-rwxr-xr-x  1 bin      7112 Nov 26 18:13 check
-rwxr-xr-x  1 bin      1546 Nov 26 18:13 chmod
-rwxr-xr-x  1 bin       484 Nov 26 18:13 chown
-rwxr--r--  1 bin       190 Nov 26 18:13 clri
-rwxr-xr-x  1 bin      1750 Nov 26 18:13 cmp
-rwxr-xr-x  1 bin      1200 Nov 26 18:13 cp
-rwsr-xr-x  1 root     2366 Nov 26 18:13 date
-rwxr-xr-x  1 bin      4930 Nov 26 18:13 db
-rwxr-xr-x  1 bin      8750 Nov 26 18:13 dc
-rwxr-xr-x  1 bin      4246 Nov 26 18:13 dd
-rwxr-xr-x  1 bin      1592 Nov 26 18:13 df
-rwxr-xr-x  1 bin       262 Nov 26 18:13 dsw
-rwxr-xr-x  1 bin       654 Nov 26 18:13 du
-rwxr-xr-x  1 bin      3842 Jan  2 19:34 dump
-rwxr-xr-x  1 bin       894 Nov 26 18:13 echo
-rwxr-xr-x  1 bin      4292 Nov 26 18:30 ed
-rwxr-xr-x  1 bin       150 Nov 26 18:13 exit
-rwxr-xr-x  1 bin      5118 Nov 26 18:13 fc
-rwxr-xr-x  1 bin       942 Nov 26 18:13 goto
-rwxr-xr-x  1 bin      1552 Nov 26 18:13 if
-rwxr-xr-x  1 bin       192 Nov 26 18:13 kill
-rwxr-xr-x  1 bin      3316 Nov 26 18:13 ld
-rwxr-xr-x  1 bin       480 Nov 26 18:13 ln
-rwsr-xr-x  1 root     2488 Nov 26 18:13 login
-rwxr-xr-x  1 bin      3112 Nov 26 18:13 lpr
-rwxr-xr-x  1 bin      5046 Nov 26 18:13 ls
-rwxr-xr-x  1 bin      4558 Nov 26 18:13 mail
-rwsr-xr-x  1 root      240 Nov 26 18:13 mkdir
-rwsr-xr-x  1 root     2330 Nov 26 18:13 mv
-rwxr-xr-x  1 bin      2518 Nov 26 18:13 nm
-rwxr-xr-x  1 bin      4710 Nov 26 18:13 od
-rwxr-xr-x  1 bin      5268 Nov 26 18:13 pr
-rwsr-xr-x  1 bin      2660 Nov 26 18:13 ps
-rwxr-xr-x  1 bin      5186 Jan  2 19:36 restor
-rwxr-xr-x  1 bin       114 Nov 26 18:13 rew
-rwxr-xr-x  1 bin      1602 Nov 26 18:13 rm
-rwsr-xr-x  1 root      292 Nov 26 18:13 rmdir
-rwxr-xr-x  1 bin      5738 Nov 26 18:13 sh
-rwxr-xr-x  1 bin      1218 Nov 26 18:13 size
-rwxr-xr-x  1 bin      5202 Nov 26 18:13 sort
-rwxr-xr-x  1 bin       510 Nov 26 18:13 strip
-rwxr-xr-x  1 bin      1804 Nov 26 18:13 stty
-rwsr-xr-x  1 root     1944 Nov 26 18:13 su
-rwxr-xr-x  1 bin       202 Nov 26 18:13 sum
-rwxr-xr-x  1 bin       144 Nov 26 18:13 sync
-rwxr-xr-x  1 bin       610 Nov 26 18:13 time
-rwxr-xr-x  1 bin      4476 Nov 26 18:13 tp
-rwxr-xr-x  1 bin       150 Nov 26 18:13 tty
-rwxr-xr-x  1 bin      1968 Nov 26 18:13 uniq
-rwxr-xr-x  1 bin      1732 Nov 26 18:13 who
-rwxr-xr-x  1 bin       682 Nov 26 18:13 write

That’s quite a lot for such an early version of Unix!

Let’s try ps, after starting some background process:

# sleep 60 &
117
 
# ps
No swap
f:     0 ???^??~??[??r[R??S? ????? R?  ? 
f:     1 /etc/init 
       7 - 
     117 sleep 60  
f:     6 /etc/update 
     118 ps
Libraries?

/lib is also interesting! Look at the size of the libraries in there:

# chdir /lib
# ls -l
total 246
-rwxr-xr-x  1 bin      7032 Nov 26 18:13 as2
-rwxr-xr-x  1 bin     16226 Nov 26 18:13 c0
-rwxr-xr-x  1 bin     20584 Nov 26 18:13 c1
-rwxr-xr-x  1 bin      9688 Nov 26 18:13 c2
-rw-r--r--  1 bin        96 Nov 26 18:13 crt0.o
-rw-r--r--  1 bin     13574 Nov 26 18:13 filib.a
-rw-r--r--  1 bin       340 Nov 26 18:13 fr0.o
-rw-r--r--  1 bin     12710 Nov 26 18:13 liba.a
-rw-r--r--  1 bin     21542 Nov 26 18:13 libc.a
-rw-r--r--  1 bin     13098 Nov 26 18:13 libf.a
-rw-r--r--  1 bin      3542 Nov 26 18:13 liby.a
-rw-r--r--  1 bin       588 Nov 26 18:13 mcrt0.o

A truly tiny libc.a with only 21542 bytes. In case you’re wondering, libf.a is the FORTRAN library.

What’s in /usr?

As we all know, the real interesting stuff is under /usr, at least on contemporary Unices. What about that ancient Unix v5?

# # chdir /usr
# ls -l
total 12
drwxr-xr-x  2 bin        32 Nov 26 18:13 adm
drwxr-xr-x  2 bin       480 Nov 26 18:13 bin
drwxr-xr-x  2 bin       496 Nov 26 18:13 c
drwxr-xr-x  2 bin       160 Nov 26 18:13 fort
drwxr-xr-x  2 bin       144 Nov 26 18:13 games
drwxr-xr-x  2 bin       144 Nov 26 18:13 lib
drwxrwxrwx  2 bin        32 Nov 26 18:13 lpd
drwxr-xr-x  2 bin       192 Nov 26 18:13 mdec
drwxr-xr-x  2 bin        96 Nov 26 18:13 pub
drwxr-xr-x  7 bin       112 Nov 26 18:13 source
drwxr-xr-x  5 bin       384 Nov 26 18:13 sys
drwxrwxrwx  2 bin        32 Nov 26 18:13 tmp

c contains a full-featured K&R C compiler, and fort is the FORTRAN compiler. games contains a couple of games.

What’s really interesting here is /usr/source where the source code for most of the commands is, and /usr/sys that features the source code of the kernel. Ken Thompson’s directory /usr/sys/ken is of particular interest, IMHO.

Hello, PDP11!

So, let’s write a Hello World program for PDP11 on Unix v5:

# chdir /tmp
 
# cat >hello.c
main()
{
  printf("Hello, PDP11!\n");
}

Just exit input with Ctrl-D. Alternatively, use /bin/ed. You remember how to use ed, don’t you? ;-)

So let’s compile this, once to assembly, and once directly to binary:

# cc -S hello.c
# cc hello.c
# ls -l
total 5
-rwxrwxrwx  1 root     1204 Mar 21 13:04 a.out
-rw-rw-rw-  1 root       40 Mar 21 13:03 hello.c
-rw-rw-rw-  1 root      165 Mar 21 13:03 hello.s
 
# ./a.out
Hello, PDP11!
 
# cat hello.s
.globl  _main
.text
_main:
jsr     r5,rsave; 2
.data
L2:.byte 110,145,154,154,157,54,40,120,104,120,61,61,41,12,0
.even
.text
mov     $L2,(sp)
jsr     pc,*$_printf
L1:jmp  rretrn

Now isn’t that sweet?

Quitting the simulator

We can quit the simulator with Ctrl-E:

Simulation stopped, PC: 001726 (MOV (SP)+,177776)
sim>

At this point, you can type ‘h(elp)’ to get a list of commands.
We simply quit the simulator with quit:

sim> quit
Goodby