Archive for October, 2019

V6 UNIX – first boot and “driving” the SIMH emulator

In the previous post, I alluded to some “extreme expect hackery” needed to configure and install a new UNIX kernel.

Note: The repository name has changed to: https://github.com/tomperrine/unix-v6-pdp11-simh-gcp

To get the most out of this post, get the files from the GitHub repo to follow along.

During the era of PDP-11 and even VAX UNIX, adding device drivers to the kernel required changing the source code. Specifically, there are a set of data structures that define the mapping from UNIX device numbers to the names of the device driver entry points (C functions). Hence, adding a device driver to the kernel requires source code to be edited and a new kernel compiled from the new sources.

The entire process is pretty well documented here.

To get from “first boot” to “booting from rk disk with all patches applied” takes a few steps:

  1. Boot from “tape” and copy an image of the root filesystem onto a simulated RK disk
  2. Boot from the RK disk, modify source code for several programs such as “df” and the kernel. Compile the new kernel, copy it into place in the root filesystem.
  3. Boot the new kernel from the new root filesystem.

This post will cover step 1 and the SIMH scripting needed to automate this process.

If we could just copy new files from “outside” (Ubuntu OS) into the file system of the “inside” or guest OS (v6 UNIX), none of this would be necessary. However, since we can’t, the only way to create files is by executing commands.

We’ll get started by figuring out how to send commands into a program that’s running inside the OS that’s inside the emulator, then (in a future post) work up to some very old-school UNIX tricks to create the needed files.

The first challenge is to pass commands to the SIMH emulator. This is done simply by giving the emulator a script file on the command line. See this example:

$ more buildunix.ini 
set cpu 11/40
set tto 7b
set tm0 locked
attach tm0 dist.tap
attach rk0 rk0
attach rk1 rk1
attach rk2 rk2
dep system sr 173030
boot rk

When you start the emulator with that script file, you get this result:

$ ./simh-master/BIN/pdp11 buildunix.ini 
PDP-11 simulator V4.0-0 Current   git commit id: 0de9b628
sim> set cpu 11/40
Disabling XQ
sim> set tto 7b
sim> set tm0 locked
sim> attach tm0 dist.tap
sim> attach rk0 rk0
sim> attach rk1 rk1
sim> attach rk2 rk2
sim> dep system sr 173030
sim> boot rk0
@

As you can see, we just gave the emulator a list of commands and they were executed by the emulator, which loads and then runs the UNIX bootloader. It’s the bootloader, running in the emulator that presents the “@” prompt. At this point, the emulator stops passing its input file to the console, leaving us “stranded” at the boot prompt. The bootloader needs the name of the kernel to load, which would normally just be entered by the user. Since we want to automate the entire process, we need to find a way to enter data but not just a a line in the script.

The emulator provides a way to SEND input into the running programs, using its own internal implementation of “expect“. This means that we can use EXPECT/SEND combinations to enter information in the programs that are running inside the OS that’s running inside the emulator. Clear as mud, right?

The “hook” is to set up an EXPECT/SEND combination BEFORE we enter the boot command, so that when the boot command executes and presents the “@” prompt, the emulator knows what to send in response. Now the script looks like this:

$ more buildunix.ini 
set cpu 11/40
set tto 7b
set tm0 locked
attach tm0 dist.tap
attach rk0 rk0
attach rk1 rk1
attach rk2 rk2
dep system sr 173030
: this sets up the rkunix information to be sent later,
: after we enter the boot rk command
expect "@" send "rkunix\r"; continue
boot rk

Which results in something more like this:

$ ./simh-master/BIN/pdp11 buildunix.ini 
PDP-11 simulator V4.0-0 Current   git commit id: 0de9b628
sim> set cpu 11/40
Disabling XQ
sim> set tto 7b
sim> set tm0 locked
sim> attach tm0 dist.tap
sim> attach rk0 rk0
sim> attach rk1 rk1
sim> attach rk2 rk2
sim> dep system sr 173030
sim> boot rk0
@rkunix
mem = 1035
RESTRICTED RIGHTS

Use, duplication or disclosure is subject to
restrictions stated in Contract with Western
Electric Company, Inc.
#

And now we have UNIX running inside the emulator, and a command prompt. At this point, our terminal is attached to the UNIX shell, and we can start to manually enter commands. But that’s not enough. We have an entire set of commands that we need to enter to add the new device drivers to the source code so we can compile a new kernel. If it was a single shell script, it would be about 70-90 lines, and of course, we still can’t just copy files into the V6 file system.

Next time, entering all the commands needed to configure and build a new kernel.

, ,

Leave a comment

PDP-11 running UNIX v6 in Google Compute Platform (GCP) using SIMH

Wow!  This post is months overdue!  I blame work, more work, Destiny2, other work, Edinburgh Fringe Festivalother other work, and beer.

This post is a quick overview of my GitHub repo (pdp-11-in-gcp) and how it works to create a fully functional UNIX system from 1976 (UNIX V6) “in the cloud”. It has everything you need to run your own piece of UNIX history.

For the most part, this is an automation of the instructions from http://gunkies.org/wiki/Installing_Unix_v6_(PDP-11)_on_SIMH

This assumes that you have a functioning GCP account with billing enabled, and have at least skimmed earlier posts in this series.

This repo includes several scripts and configuration files:

* launch-pdp11.sh – The master script creates a place to run the SIMH emulator, and builds the emulator. Part of this process is loading another script on to the GCP instance.

* update-os-build-simh.sh – This script is copied on to the GCP Ubuntu instance and gets the SIMH PDP-11 emulator running in the instance. When this script completes, you have a running Ubuntu system with a PDP-11 emulator ready to install v6 UNIX.

The end of the launch-pdp11.sh script provides instructions on how to install V6 UNIX into the emulator. This requires manually running three commands while logged into the GCP Ubuntu instance. Due to limitations of EXPECT, there are a few places where you will need to manually halt the emulator (^E).

* simh-master/BIN/pdp11 tboot.ini – This starts the emulator and does a “tape boot” from an emulated tape image and copies the minimal root filesystem on to the emulated RK disk (which is a file on the Ubuntu host).

* simh-master/BIN/pdp11 buildunix.ini – This script uses extreme expect hackery to do LOTS of customization of the kernel to support an RK disk 

* simh-master/BIN/pdp11 normalboot.ini – boots the fully functional PDP-11 with all software. Use this for all subsequent boots of the UNIX guest

One of the most fun parts of this project was dealing with SIMH’s internal EXPECT function. In the “olden days” you had to change the kernel source code to configure tables for each device driver that you wanted included in a new kernel.  I’ll show some of that in the next post.

, , , ,

1 Comment

%d bloggers like this: