Monthly Archives: July 2015

Installing BSD 2.9 on a DEC Pro-350, Part V – Building the kernel

A great test of whether a UNIX operating system is installed correctly is if you can recompile the kernel and then run that kernel. Like most UNIX Operating Systems, BSD 2.9 provides a mechanism for rebuilding the kernel. The procedure is documented here in section 5:

But I will provide a walk-through of the necessary steps below.

Note that you will need to the 16 disk usr set in order to get the kernel sources. You can either use this set during the installation of BSD, or install them at a later time using the restor command. Note that if you choose the latter, the contents of /usr will be destroyed. The command to restore the 16 disk set is the same as documented earlier:

restor rf /dev/rr51 /dev/rrd0c

You can, of course, substitute /dev/rr50 if you like.

The instructions work, but the BSD distribution is missing some files that are needed for building the kernel. Those files are:


Unfortunately, you will not (yet) be able to find all of these files in a single distribution. One of the goals of this blog is to put together one distribution that has everything needed, but that will have to wait until I know everything that is needed!

The good news is everything I’ve needed so far is somewhere under this directory structure:

Even better, it seems all you need is these two distributions:

If you extract the contents of the tar files from the tarfiles directory in the first link, you will have 95% of what you need. If you also extract the root.tar.gz and usr.tar.gz files from the second link, you can then find the remaining 5%. Note that the files aren’t really gzipped – they are simply tar files with a .gz extension.

Once you have the kernel sources installed and the above missing files in place, you need to configure the kernel. To do that, cd to /usr/net/sys/conf and type config PRO. This process creates the necessary files in /usr/net/sys/PRO and takes about 5 minutes.

Once the configuration is done, you need to edit a couple of files in the /usr/net/sys/PRO directory. Those files are:


And depending on what usr set you installed, you may need to edit this file:


In param.c, change this line:

#define HZ 60 /* Ticks/second of the clock */
#define HZ 66 /* Ticks/second of the clock */

In localopts.h, uncomment this line:

#define SMALL /* for small sys: smaller hash queues, etc. */

In Makefile, remove r5.o from this line:

OV2 = text.o ureg.o malloc.o sys1.o main.o mem.o sig.o trap.o clock.o rd.o r5.o xp.o hp.o

And add it to this line:

OV4 = ttyold.o ttynew.o tty.o prim.o kl.o partab.o nami.o hk.o pc.o r5.o

Failure to do so results in a message similar to below:

size unix
text data bss dec oct
7424 + 6356 + 13940 = 27720 = 66110 unix
103296 total text, overlays: (13056,16448,15808,10368,12928,15040,12224)
./checksys -b unix
Overlay 2 too large 16448 bytes.
System will occupy 173056 bytes of memory (incl buffers, clists and net).
*** Error code 1

Next, check the value of OVLY_TABLE_BASE in /usr/include/sys/koverlay.h. If it’s set to 01000, change it to 0450. If you don’t, you will end up with a kernel that hangs at the DIGITAL splash screen.

To avoid this warning during compilation of checksys.c:

cc -V -I. -I/usr/include -O -o checksys checksys.c
ld:/usr/lib/libovc.a(__.SYMDEF): out of date (warning)

you may want to run ranlib on /usr/lib/libovc.a before continuing.

With the configuration out of the way, the next step is to cd to /usr/net/sys/PRO and type make depend. This builds the module dependencies and takes about 15 minutes.

The last step is to simply type make in the /usr/net/sys/PRO directory. This step actually builds the kernel and takes about 3 hours. If during compilation you get an error such as this:

Make: Don't know how to make /usr/include/signal.h. Stop.
*** Error code 1

It means that the code you are compiling is newer than the include files, which shouldn’t be the case. When I received this error, the date on my system include files were the year 1910! Considering that the UNIX epoch didn’t start until 1/1/1970, I’m not sure how this happened. Ensuring that the date is something more recent and then issuing a touch on the include files fixes the problem. While we’re on the subject of UNIX dates, you can make BSD 2.9 somewhat Y2K compliant by changing the base year from 1900 to 2000 inside of date.c. Then all years issued to the date command will be based off the year 2000. There’s probably some work in the kernel that needs to be done to be fully Y2K compliant, but changing only the date code has been working thus far.

Once the build is finished, you will have a new kernel named unix in the /usr/net/sys/PRO directory. To be safe, rename this file to something other than unix to prevent accidentally clobbering the stock unix kernel. Something like prounix is good. Then copy the prounix file to /. Now you have a new kernel installed and it’s time to test it.

To test your new kernel, you need to have the maintenance cable installed as described previously. With the cable installed, bring the system to single-user mode, sync the disks, and power off the Pro-350. You must power off the Pro-350 – a soft reboot will not work.

# shutdown +1
# sync
# sync
Power off the Pro

Now, fire up your terminal program, set the comm parameters to 9600,7,N,1 and turn on the Pro-350. In a moment, you will see the 40boot message. At the prompt, type rd(0,64)prounix. If all goes well, in a minute or so you will see messages similar to this on the console:


Berkeley UNIX (Rev. 2.9.54) Thu Nov 14 12:32:20 EST 1985

/unix is not the running version
Configuration setup error
Erase=^?, kill=^U, intr=^C

Note that you are in single-user mode. The error message is not really an error – it’s just a warning that the booted kernel (prounix) is not the same as the configured kernel (unix). If after testing you want to install your new kernel, rename the original kernel (DO NOT DELETE IT) to something memorable like stockunix, and then rename your test kernel from prounix to unix. Then follow the installation instructions we did earlier to make the kernel bootable. Refer to section 2.4 of the BSD documentation for more information.

Installing BSD 2.9 on a DEC Pro-350, Part IV – Transferring files

Now that I have a Pro-350 running BSD 2.9, but without an Ethernet card, a solution is needed for transferring files to and from it. The first thing that comes to mind, as mentioned in the notes, is to use the venerable cu command. Using cu to transfer files is as old as UNIX itself, and should work.

So I connected up a NULL modem cable from the serial port of the Pro-350 (a 25 pin D-SUB connector) to my Linux box. In BSD, the serial port equates to /etc/tty01 (the printer port is /etc/tty00). I made sure that I enabled /etc/tty01 for logins in BSD as mentioned at the end of part III, and then fired up cu on Linux:

cu -l /dev/ttyS1 -s 9600

Sure enough, it connected and I was presented with the login prompt. After logging in, I initiated the put command (~p or ~%put) and attempted to transfer a file. After a few seconds, the terminal started echoing back what appeared to be some characters from the original file, and then the connection dropped. Unfortunately, the file didn’t transfer. Looking through the cu manual page, I tried various options to try and fix the problem, but nothing seemed to work. Reading this in the BUGS section of the man page didn’t fill me with confidence:

This program does not work very well.

After seeing that, I decided to try using my Solaris box instead.

Unfortunately, Solaris turned out to have the same problem. However, the Solaris man page did offer this tidbit that was missing from the Linux man page:

The use of ~%put requires stty(1) and cat(1) on the remote side. It also requires that the current erase and kill characters on the remote system be identical to these current control characters on the local system. Backslashes are inserted at appropriate places.

The use of ~%take requires the existence of echo(1) and cat(1) on the remote system, and that the remote system must be using the Bourne shell, sh. Also, tabs mode (see stty(1)) should be set on the remote system if tabs are to be copied without expansion to spaces.

Aha! Is this what I was missing? After verifying that these conditions were indeed met, I decided to manually set the erase and kill characters. After doing that, the echos stopped and cu appeared to work (there were no errors). However, no file was transferred.

Long story short, I spent many hours trying cu from Linux to BSD and Solaris to BSD, trying both puts and takes unsuccessfully. I still do not know why it didn’t work, but assume it’s due to the fact that the cu on BSD 2.9 is over 30 years old, whereas the one on Linux or Solaris is probably 1/2 that. Perhaps there is some sort of incompatibility between the two. I wouldn’t think there would be, but I don’t know what else the problem could be.

With cu out of the equation, the next logical step was to try kermit. But how do I transfer the source files to the Pro-350? Or the binary if I could find one? There are too many files to type in manually, and cutting/pasting between terminal windows doesn’t work very well on the Pro-350 side.

As luck would have it, my friends Sidik and Tarik over at the Xhomer project ( had for some time an interest in getting BSD 2.9 running on their Pro-350 simulator. With the help of my instructions, they were able to get a BSD 2.9 image up and running on Xhomer! As a bonus, they created a utility, rx2f, that enables you to create a BSD RX50 image of a file on Linux (up to 400K in size) that can then be written to a 5.25″ floppy drive. That floppy can then be put into the Pro-350 running BSD 2.9 and extracted. Their work is still in progress, but you can find it here:

Using rx2f, I was able to transfer files such as kermit to the Pro-350. For my first attempt, I tarred up the kermit sources on Linux, used split to make 400K chunks, wrote them to a 3.25″ floppy on Linux, and then copied those chunks to DOS (As explained in part I, I had no luck using Linux to create RX50 floppies). Once on DOS, I used BIN2IMD to create IMD files for use in ImageDisk, and then wrote the chunks to 5.25″ floppies (again, as explained in part I). Then once in BSD, I retrieved the files from the RX50 floppies, used cat to glue the chunks back together and then tried to use tar to extract them. Guess what? The stock BSD install doesn’t contain tar! As hard as it is to believe, it’s true. So I found the tar binary in the original sources:

And then used rx2f to transfer tar over to the Pro-350. After that, I was able to extract the kermit sources.

Armed with a mechanism to get files onto the Pro-350, I attempted to compile ckermit. Some minor edits were needed, but in the end, I got a successful build. However, running it resulted in the following error:

kermit:too big

Clearly the binary is too big to load into memory. Since I have 350K of memory, I found this strange.

To try and shrink the binary, I added -O and -V options to cc and recompiled. The binary was smaller, but still wouldn’t load. Other than adding more memory or trying to reduce the memory footprint of kermit by hacking the source code, I’m not sure what to do.

About this same time, my friends at Xhomer had gotten zmodem to compile and run on their BSD emulator. Figuring I could do the same, I transferred the zmodem sources via rx2f and compiled zmodem on the Pro-350. You can find the zmodem sources here:

The sources are for 2.11, but worked for Xhomer and so should work on the Pro-350 as well.

As expected, the source compiled without issue. However, running it proved to be problematic. Like cu, I couldn’t get transfers in any direction working. I tried both sz and rz, as well as both tty00 and tty01. The best I could get were timeout errors and ZNAKs. I tried invoking the utilities after logging in through the tty port, as well as stand-alone with commands similar to below:

rz /dev/tty01
sz file /dev/tty01

Nothing seemed to work. My best guess is that zmodem needs to be 8-bit, but BSD seems to be 7-bit. Why does it work on the simulator? I’m guessing it’s because they are using pseudo-ttys.

With kermit and zmodem not working, I tried gkermit. Unlike ckermit, gkermit to load and run, but like zmodem, it failed to transfer any files. The G-Kermit documentation did provide some potentially useful information:

G-Kermit is always on the “far end” of a connection, on a Unix system that you have made a connection to from a terminal emulator by dialup, network, or direct serial. If you have a direct or dialup serial connection into Unix, use the “stty -a” or “stty all” command to see if your Unix terminal driver is conditioned for the appropriate kind of flow control; if it isn’t, very few applications (including gkermit) will work well, or at all.

Interesting. As far as I can tell, there is no flow control available in BSD 2.9. Or at least it’s not documented in the stty man page. Perhaps this is the root of the problem.

So at this point, I am left using rx2f. I’m grateful that the folks at Xhomer provided me with this utility, else I couldn’t transfer any files at all.