Installing OmniOS KVM/QEMU guest onto a Linux host zvol

I originally wanted to install Solaris x86 as a KVM guest, but had problems getting the network to function. The installation itself was easy enough, but all attempts to get networking to work failed. So I decided to try an Illumos distribution, as that would meet the requirements I was looking for.

Since OpenIndiana is the de facto Illumos distribution, I started with that. Unfortunately, it turned out to have the same problem. So I decided to try OmniOS, only to discover it too had the same problem. At this point, I wasn’t sure if it was my Linux KVM that was at fault, since three operating systems failed with the same problem. However, since I have several other operating systems running as KVM guests on Linux and they all work fine, I was still inclined to think it was the distro.

Neither Solaris x86 or OpenIndiana had any new updates, but my OmniOS distro was a little old – I had downloaded the OmniOS_Text_r151012.iso ISO sometime ago. So I checked and found a newer version – OmniOS_Text_r151014.iso. After downloading and installing it, I had a functional network! Based on this, I can only conclude that the reasons Solaris x86 and OpenIndiana failed are due to internal problems with those distros, and not some problem with Linux KVM. Either that or there is some magic KVM setting I’m not familiar with that is needed to get them to work (and I tried a bunch of them).

Installing OmniOS is pretty straight forward. Aside from answering a couple of questions, the installation is totally automatic. The only thing you need to do after installation is manually configure the network. Here are the commands I used to install OmniOS as a KVM guest under Linux.

Create the zvol:

zfs create -p -V 16G rpool/kvm/omnios11/disk0

Create the VM:

qemu-system-x86_64 -enable-kvm -cpu host -m 8192M -drive format=raw,file=/dev/zvol/rpool/kvm/omnios11/disk0 -cdrom OmniOS_Text_r151014.iso -boot d -smp 2

Start the VM:

qemu-system-x86_64 -enable-kvm -cpu host -m 8192M -drive format=raw,file=/dev/zvol/rpool/kvm/omnios11/disk0 -net nic,model=e1000,netdev=net0 -netdev tap,id=net0 -smp 2

Once the VM is started, login as root with no password and configure networking:

ipadm create-if e1000g0
ipadm create-addr -T static -a 172.16.0.175/16 e1000g0/v4
route -p add default 172.16.0.1
echo 'nameserver 172.16.0.10' >> /etc/resolv.conf
cp /etc/nsswitch.dns /etc/nsswitch.conf

You can find more information on setting up OmniOS here:

http://omnios.omniti.com/wiki.php/GeneralAdministration

Installing FreeBSD KVM/QEMU guest onto a Linux host zvol

This configuration is so simple, it’s hardly worth blogging about. But if for no other reason than to keep the commands I used handy, here it is.

Create the zvol:

zfs create -p -V 16G rpool/kvm/freebsd10/disk0

Create the VM:

qemu-system-x86_64 -enable-kvm -m 4096M -drive format=raw,file=/dev/zvol/rpool/kvm/freebsd10/disk0 -cdrom FreeBSD-10.2-RELEASE-amd64-dvd1.iso -boot d

Start the VM:

qemu-system-x86_64 -enable-kvm -m 4096M -drive format=raw,file=/dev/zvol/rpool/kvm/freebsd10/disk0 -netdev user,id=net0 -device e1000,netdev=net0 -smp 2

That’s it!

If you prefer to use bridge networking, use the below command instead:

qemu-system-x86_64 -enable-kvm -m 4096M -drive format=raw,file=/dev/zvol/rpool/kvm/freebsd10/disk0 -net nic,model=e1000,netdev=net0 -netdev tap,id=net0 -smp 2

For more details on bridge networking, see my previous post.

Using bridged networking with KVM/QEMU guests on a Linux host

Using KVM to virtualize guest operating systems under Linux is great, but the default networking configuration doesn’t allow incoming connections to the VM. This is not peculiar to KVM – this is the default for most (all?) virtualization technologies, including VirtualBox.

If, like me, you need to access you guest VM’s from the outside, then you need to setup bridge networking. There are plenty of resources on the web on how to do this, and this blog is simply a quick overview of the steps I took to enable bridge networking under KVM. It will serve as a reminder to my self of the steps I took, and possibly help others out as well.

Below is a list of the sites I used for setting up bridged networking with KVM under Linux:

https://help.ubuntu.com/community/NetworkConnectionBridge
http://drupal.bitfunnel.net/drupal/macosx-bridge-qemu
http://en.blog.guylhem.net/post/88201449689/running-qemu-with-tap0-and-nat-under-osx-109
http://superuser.com/questions/42249/how-to-bridge-two-ethernet-ports-on-mac-os-x

In a nutshell, setting up a bridge on Linux means installing the necessary bridge software and editing the /etc/network/interfaces file, both of which are described here:

https://help.ubuntu.com/community/NetworkConnectionBridge

If you’re like me, seeing a working config file gets you a long way, so below is my /etc/network/interfaces file. For reasons not related to bridging, my network is setup as a class B network, so you will probably have to adjust the various addresses accordingly:

$ cat /etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

iface eth0 inet manual

auto br0
iface br0 inet static
    address 172.16.0.190
    network 172.16.0.0
    netmask 255.255.0.0
    broadcast 172.16.0.255
    gateway 172.16.0.1
    dns-search mydomain.com
    dns-nameservers 172.16.0.10
    bridge_ports eth0
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0

Once bridging is setup on the Linux host, all that needs to be done is start QEMU with the correct network options, and then edit the guest network settings. The options to use for QEMU are:

-net nic,vlan=0
-net tap,vlan=0,ifname=tap0

Note that these options replace the existing QEMU network options, and are not to be used in conjunction with them.

It is these args that inform QEMU that you wish to use bridged networking.

To use bridge networking on Windows 7, add the above two arguments to your QEMU start line and then setup your network manually within Windows 7. For example, if you use this command for non-bridge networking:

qemu-system-x86_64 -enable-kvm -m 8192M -cpu host -drive file=/dev/zvol/rpool/kvm/windows7/disk0 -netdev user,id=vlan0 -net nic,model=e1000,netdev=vlan0 -smp 2

Then use this for bridged networking:

qemu-system-x86_64 -enable-kvm -m 8192M -cpu host -drive file=/dev/zvol/rpool/kvm/windows7/disk0 -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 -smp 2

Note that this assumes you have previously setup bridge networking support in Linux. Also, you must run QEMU as root in order to use bridge networking.

To use bridge networking on OS X Mountain Lion, use the above two arguments for networking in your QEMU start line. For example:

qemu-system-x86_64 -enable-kvm -m 4096 -cpu core2duo -machine q35 -usb -device usb-kbd -device usb-mouse -device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" -kernel ./chameleon_svn2534_boot -smbios type=2 -device ide-drive,bus=ide.2,drive=MacHDD -drive id=MacHDD,if=none,format=raw,file=/dev/zvol/rpool/kvm/mountain-lion/disk0 -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 -monitor stdio -smp 2

And then setup your network manually within Mountain Lion using these commands:

sudo ifconfig bridge0 create
sudo ifconfig bridge0 addm en0
sudo ifconfig bridge0 up

These commands aren’t necessary, but may be useful if you make a mistake:

sudo ifconfig bridge0 down
sudo ifconfig bridge0 deletem en0
sudo ifconfig bridge0 destroy

To use bridge networking on OS X Mavericks, use the OS X Network utility as described in the above posts to add a bridge, making sure to add your Ethernet device (en0) to it. Then add use the two QEMU networking options above in your QEMU command-line along with the virtio driver. For example:

qemu-system-x86_64 -enable-kvm -m 4096 -cpu core2duo -machine q35 -usb -device usb-kbd -device usb-mouse -device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" -kernel ./chameleon_svn2534_boot -smbios type=2 -device ide-drive,bus=ide.2,drive=MacHDD -drive id=MacHDD,if=none,format=raw,file=/dev/zvol/rpool/kvm/mavericks/disk0 -net nic,model=virtio,vlan=0 -net tap,vlan=0,ifname=tap0 -monitor stdio -smp 2

Installing OS X KVM/QEMU guest onto a Linux host zvol

First off, let me start by saying that most of what you read in this post is information I’ve gathered from other sources. Why then have a blog about the subject? Because for some reason, none of the procedures on the other sites completely worked for me. Using the knowledge learned from other sites, along with a few minor tweaks and trial and error, I finally got a sequence that worked for me. This blog will serve as a reminder to me of what I did should I need to do it again and may also help other people who are in the same situation I was in.

In my quest to get an OS X KVM guest under Linux, I visited many, many sites. I can’t be 100% sure that I’ve included all those sites below, but here is a list of sites I’m positive I’ve frequented in order to get OS X running under KVM. 90% of what I present here is a derivative of their work:

http://blog.ostanin.org/2014/02/11/playing-with-mac-os-x-on-kvm
http://www.contrib.andrew.cmu.edu/~somlo/OSXKVM
http://kernelpanik.net/running-mac-osx-yosemite-on-kvm
https://macosxvirtualmachinekvm.wordpress.com/guide-mac-os-x-vm-on-unraid
http://forums.appleinsider.com/t/159955/howto-create-bootable-mavericks-iso

I have tested the procedure below with Mountain Lion, Mavericks and Yosemite. For Mavericks and Yosemite, there are extra steps needed to get networking going, but the steps are manageable.

The first problem I encountered was how to create a usable ISO image from the OS X installers obtained through the App Store. Some of the sites claimed you could simply use dd under Linux, while others said you could use the Mac Disk Utility to extract the image. Yet other sites had long sequences of commands and/or scripts to run that would create the ISO for you. There is even a createinstallmedia command on Mavericks and Yosemite. For whatever reason, none of these worked for me. The installation method either failed altogether or presented me with this error when trying to create the VM:

With Mountain Lion or Mavericks:

Can't find /mach_kernel

With Yosemite:

Can't find /System/Library/Kernels/kernel

Since having an ISO image of OS X is step #1, I do not know how other people have gotten OS X to work under KVM by following the directions on the web for creating an ISO. I’m assuming all those people can’t be wrong and I must be the problem, but since I couldn’t get a working ISO using the procedures they describe, I’ve slightly modified those procedures to get a working ISO. To me, it seems the problem is that the bootloader used to bootstrap the system (more on that later) can’t/isn’t looking for the kernel inside of the package (which makes perfect sense to me). To compensate, I’ve extracted the kernel from the package and put them where the bootloader wants them to be.

Note that you will need a Mac in order to create the ISO images as described below. I’m sure there is a way to achieve the same results using Windows or Linux, but since all of the posts I’ve read used a Mac, and I happen to have a Hackintosh that I recently built handy, I just created the ISO on my Hackintosh. If you have another way to create the ISO or already have a working one, then you can skip the ISO creation stuff.

From poking around the OS X installers and reading other posts, I learned that the kernel name and location changed in Yosemite, so that explains why I get two different errors. The next question is why isn’t the kernel present in the OS X Installer? Examining the installer does indeed show there is no /mach_kernel in the Mountain Lion or Mavericks installer, or /System/Library/Kernels/kernel in the Yosemite installer. However, digging a little deeper, I learned that the kernels do exist in a .pkg file inside of the installer. For Mountain Lion and Mavericks, that package is BaseSystemBinaries.pkg. For Yosemite, it’s Essentials.pkg. After downloading the OS X Installer from the App Store, the packages containing the kernel can be found by:

1) Right-clicking the “Install OS X Mountain Lion|Mavericks|Yosemite” icon in Finder
2) Selecting “Show Package Contents”
3) Opening the resulting “Contents” folder
4) Opening the “SharedSupport” folder
5) Double-clicking the “InstallESD.dmg” icon
6) Opening the “Packages” folder

If you install the Pacifist program from https://www.charlessoft.com, you can then right-click the correct package (BaseSystemBinaries.pkg or Essentials.pkg) and select “Open With->Pacifist”. From there, you can select the “mach_kernel” file for Mountain Lion or Mavericks and hit “Extract To…” to extract the kernel. For Yosemite, you extract “System/Library/Kernels/kernel” instead.

With the kernel now extracted, I figured I could copy it to the correct place needed by the bootloader and get past the above error. To accomplish this, I slightly modified the script that can be found here: http://forums.appleinsider.com/t/159955/howto-create-bootable-mavericks-iso. Basically, I inserted a line in the script to copy the kernel into the ISO during creation:

cp -rp ~/Desktop/mach_kernel /Volumes/install_build

Here is the script in its entirety, with my one-line change:

# Mount the installer image:
hdiutil attach /Applications/Install\ OS\ X\ Mountain\ Lion.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app

# Convert the boot image to a sparse bundle:
hdiutil convert /Volumes/install_app/BaseSystem.dmg -format UDSP -o /tmp/mountain-lion

# Increase the sparse bundle capacity for packages, kernel, etc.:
hdiutil resize -size 8g /tmp/mountain-lion.sparseimage

# Mount the sparse bundle target for further processing:
hdiutil attach /tmp/mountain-lion.sparseimage -noverify -nobrowse -mountpoint /Volumes/install_build

# Remove Package link and replace with actual files:
rm /Volumes/install_build/System/Installation/Packages
cp -rp /Volumes/install_app/Packages /Volumes/install_build/System/Installation/

cp -rp ~/Desktop/mach_kernel /Volumes/install_build/

# Unmount both the installer image and the target sparse bundle:
hdiutil detach /Volumes/install_app
hdiutil detach /Volumes/install_build

# Resize the partition in the sparse bundle to remove any free space:
hdiutil resize -size $(hdiutil resize -limits /tmp/mountain-lion.sparseimage | tail -n 1 | awk '{ print $1 }')b /tmp/mountain-lion.sparseimage

# Convert the sparse bundle to ISO/CD master:
hdiutil convert /tmp/mountain-lion.sparseimage -format UDTO -o /tmp/mountain-lion

# Remove the sparse bundle:
rm /tmp/mountain-lion.sparseimage

# Rename the ISO and move it to the desktop:
mv /tmp/mountain-lion.cdr ~/Desktop/mountain-lion.iso

Be sure to have the kernel you extracted in your Desktop directory, or edit the script accordingly.

After running the script, you will have a mountain-lion.iso under Desktop that is suitable for creating a KVM OS X guest. With a few edits around the operating system names, this script also works with Mavericks and Yosemite, but for Yosemite, the extracted kernel name is “kernel” and needs to be copied to /System/Library/Kernels instead:

cp -rp ~/Desktop/kernel /Volumes/install_build/System/Library/Kernels

Note that once created, you can also burn the ISO to a DVD and restore it later using dd:

dd if=/dev/cdrom of=mountain-lion.iso

This will prevent you from having to repeat this procedure should you need to do it again at a later time.

With the ISO creation done, it is now time to create a zvol. You can do that with the following command:

zfs create -p -V 60G rpool/kvm/mountain-lion/disk0

This will create a 60GB zvol named mountain-lion in the rpool zpool, under dataset kvm/mountain-lion. You can of course substitute the names and size as with your own values.

Next, it’s time to create the actual VM. From what I’ve read, you need to be running kernel version 3.15 or later, as well as QEMU 2.2 or later. I’m not sure if this is true, but I heeded the warning and upgraded both my kernel and QEMU versions.

Before continuing, you need a copy of the Chameleon bootloader. You can find it on some of the above links, or download it here:

Chameleon Bootloader

Assuming you have all the necessary tools installed (KVM, QEMU, etc.), creating the VM is as simple as:

qemu-system-x86_64 \
-enable-kvm -m 4096 \
-cpu core2duo \
-machine q35 \
-usb -device usb-kbd \
-device usb-mouse \
-device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" \
-kernel ./chameleon_svn2534_boot \
-smbios type=2 \
-device ide-drive,bus=ide.2,drive=MacHDD \
-drive id=MacHDD,if=none,format=raw,file=/dev/zvol/rpool/kvm/mountain-lion/disk0 \
-net nic,model=e1000,netdev=net0 \
-netdev tap,id=net0 \
-monitor stdio \
-device ide-drive,bus=ide.0,drive=MacDVD \
-drive id=MacDVD,if=none,snapshot=on,file=./mountain-lion.iso
-smp 2

Note that for Yosemite, you must disable msrs first by running this command as root:

echo 1 > /sys/module/kvm/parameters/ignore_msrs

After running the above qemu-system-x86_64 command, QEMU will start a VNC session that you can connect to in order to finish the installation. I used the TightVNC viewer on Linux, and usage couldn’t be simpler:

vncviewer localhost:5900

This will connect the VNC viewer to localhost port 5900, which is the default. Note that if you have another QEMU instance running, you may need to change the port number, as they increase sequentially with each instance.

Once connected, you will be a the Chameleon boot prompt. I found that I needed to enter the boot option “GraphicsEnabler=No” in order to get a successful installation, so you may need to do the same. At the boot: prompt, type:

boot: GraphicsEnabler=No

After that, the Mac OS X installation should start. Note that for some reason, the installation exits the VNC viewer shortly after starting, and so you have to reconnect a second time. Once connected the second time, it may be a while before the installation splash screen appears. If after 5 or so minutes it doesn’t appear, simply exit QEMU and try again.

Once you’ve reached the splash screen, the first thing you will notice is that the virtual VNC cursor doesn’t quite follow the real cursor. This makes it painful to navigate the menus, so learning to use the keyboard, particularly the Enter and Space keys, will be beneficial. Later on you can get around this issue by using the native Mac Screen Sharing utility instead of the QEMU VNC server.

Now you can follow the usual directions for installing OS X. Don’t forget to partition your zvol using the Disk Utility during installation!

Once the installation is finished, OS X will reboot and you will be back to the Chameleon boot prompt, but this time with two options to boot. The first option is the ISO installer, named “OS X Base Installer”, and the second option is the KVM VM, and is named Mountain Lion, Mavericks or Yosemite. Be sure to select the VM when booting, else the installer will start all over again. If that happens, simply reboot again and choose the right option.

Finish the installation steps, and if all goes well, you should now have an OS X KVM guest running under Linux!

If you installed Mountian Lion, you are all set. If you installed Mavericks or Yosemite, there are a couple of more steps you need to do in order to get networking functional. Apparently, the e1000 driver does not work under Mavericks or Yosemite and so you must install the virtio driver which you can find in the above links or download it here:

Virtual IO Driver

Now the problem is getting the driver to the guest when you have no network. Fortunately, QEMU provides a mechanism for sharing a FAT folder between the host and guest. Unfortunately, the procedure didn’t work for me. After hours of debugging, it turned out that my problem was the procedure didn’t work with the version of QEMU I was using – 2.3.94, but did work with 2.0.0. So I fired up 2.0.0 just to get the driver over to the guest. To create a shared FAT folder, create a directory named VirtIoNetDrv and download the virtio driver there. Then start QEMU 2.0.0 using the same command above, but with the following two additions:

-device ide-drive,bus=ide.4,drive=fatdrive
-drive id=fatdrive,file=fat:ro:VirtIoNetDrv

Also, change the e1000 line to virtio:
For Mavericks:
-net nic,model=virtio,netdev=net0
For Yosemite:
-net nic,model=virtio,netdev=net0,vectors=0

When the OS X guest starts, you will have a drive mounted from which you can copy the virtio driver from. After copying it somewhere to the guest OS, restart the newer version of QEMU as originally described (without the fatdrive arguments, but with the virtio driver instead of e1000). Install the virtio driver and configure networking. That’s it! I imagine this QEMU quirk will be worked out in a future version, and when it does, you won’t have to fire up an older version. It’s also possible that perhaps the way shared FAT folders work in the newer QEMU has changed, and so the procedures on the web for sharing folders does not work.

After installation, you can start the VM by using a slightly simpler QEMU command:

qemu-system-x86_64 \
-enable-kvm -m 4096 \
-cpu core2duo \
-machine q35 \
-usb -device usb-kbd \
-device usb-mouse \
-device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" \
-kernel ./chameleon_svn2534_boot \
-smbios type=2 \
-device ide-drive,bus=ide.2,drive=MacHDD \
-drive id=MacHDD,if=none,format=raw,file=/dev/zvol/rpool/kvm/mountain-lion/disk0 \
-monitor stdio \
-net nic,model=e1000,netdev=net0 \
-netdev tap,id=net0 \
-smp 2

For Mavericks and Yosemite, don’t forget to substitute virtio for e1000, and for Yosemite only, don’t forget to add the vectors=0 option.

Note that you do not need to use the “GraphicsEnabler=No” option to boot – you can simply press Enter. To avoid having to press Enter at all, you can tell OS X to skip the bootloader prompt. To do so, simply create the file /Extra/org.chameleon.boot.plist with these contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Timeout</key>
    <string>5</string>
    <key>EthernetBuiltIn</key>
    <string>Yes</string>
    <key>PCIRootUID</key>
    <string>1</string>
</dict>

After that, OS X will boot automatically without the need to press Enter at the bootloader.

As mentioned earlier,when you use the VNC provided with QEMU, the virtual mouse pointer doesn’t follow the native mouse pointer, which makes it difficult to use. This can be fixed by enabling screen sharing through OS X and using that instead. But to do that, you will first need to setup bridge networking, which you can read about in my next post.

Installing Windows 7 KVM/QEMU guest onto a Linux host zvol

Though Linux is my desktop of choice, some of my programming tasks require me to run other operating systems. Rather than have multiple machines running various operating systems and/or a single machine with several boot partitions, I have in the past opted for virtualizing these other operating systems using VirtualBox under Linux. That is, until recently, when I switched from using VirtualBox to KVM/QEMU. There’s nothing wrong with VirtualBox, but for what I do, KVM made more sense. And since I’m running ZFS under Linux, using a zvol for the operating systems seemed a natural fit.

Creating a Windows 7 KVM/QEMU guest on a zvol under Linux is easy. First, create the zvol:

zfs create -p -V 60G rpool/kvm/windows7/disk0

This will create a 60GB zvol named windows7 in dataset kvm in the zpool named rpool. You can of course substitute the zpool/dataset names as you see fit.

With the zvol created, insert a copy of Windows 7 into your CD drive and create the guest:

qemu-system-x86_64 -enable-kvm -m 8192M -cpu host -drive file=/dev/zvol/rpool/kvm/windows7/disk0 -cdrom /dev/cdrom -boot d -smp 2

With any luck, qemu will start the Windows 7 installation. Just follow the instructions as you would a normal Windows installation.

Once installation is complete, you can use this command to start the Windows 7 guest:

qemu-system-x86_64 -enable-kvm -m 8192M -cpu host -drive file=/dev/zvol/rpool/kvm/windows7/disk0 -netdev user,id=vlan0 -net nic,model=e1000,netdev=vlan0 -smp 2

This will give your Windows 7 VM a network using DHCP, in which you can communicate from the VM to the outside world, but not the other way around. If you wish to be able to access your VM from the outside, you will need to use bridge networking instead, which you can read about in my future post.

That’s all there is to it!

Note that the -cpu host option is critical – if you forget it, the installation will give you the dreaded BSOD with a STOP 0x0000005D error. And to use the -cpu host option, you must also specify the -enable-kvm option.

If you’d prefer to install to an image file rather than a zvol, you can do that simply by creating the image using QEMU and then substituting the image file for the zvol:

qemu-img create -f qcow2 windows7.img 60G

qemu-system-x86_64 -enable-kvm -m 8192M -cpu host -drive file=windows7.img -cdrom /dev/cdrom -boot d -smp 2

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:

http://minnie.tuhs.org/PUPS/Setup/2.9bsd_setup.pdf

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:

/usr/bin/awk
/usr/bin/sed
/usr/include/sys/wait.h
/usr/include/sys/cnio.h
/usr/include/sys/dcreg.h
/usr/lib/libovc.a

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:

http://www.tuhs.org/Archive/PDP-11/Distributions/ucb

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

http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9-derivatives/2.9bsd4pro350-kcwellsc
http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9BSD

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:

param.c
localopts.h
Makefile

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

/usr/include/sys/koverlay.h

In param.c, change this line:

#define HZ 60 /* Ticks/second of the clock */
to:
#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).
**** SYSTEM IS NOT BOOTABLE.
*** 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:

mem=351872

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

CONFIGURE SYSTEM:
/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 (http://xhomer.isani.org/xhomer) 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: http://xhomer.isani.org/xhomer/BSD/bsd.html.

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:

http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9-derivatives/2.9bsd4pro350-kcwellsc/tarfiles

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:

http://www.retro11.de/ouxr/211bsd/usr/src/local/zmodem

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.

Installing BSD 2.9 on a DEC Pro-350, Part III – Installation

OK, so with an understanding of how to create RX50 floppies from the images, as well as what images to use, we are now ready to begin the actual installation. I’d like to point out that these instructions are basically typed versions of the hand-written notes found here:

http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9-derivatives/2.9bsd4pro350-kcwellsc/document

Preparation

1) As discussed in Part I, first create the floppy distribution using ImageDisk. You will need nine 5.25″ floppy disks if you are using the 3 disk usr set, and twenty-five if using the 16 disk usr set. You will also need a DOS PC, a copy of ImageDisk and, of course, the images. Use ImageDisk to create the installation floppies from the *.IMD images, using these settings:

Sides: One
Double-step: Off
R/W gap: 7
Format gap:14

You can find the IMD images here:

Pro-350 BSD 2.9 IMD images

And the ImageDisk program here:

ImageDisk 1.17 for DOS

Note that during installation of BSD, the maintenance floppy must not be write-protected, else you get this error:

r50a: hard error on 10 cs0=370 csi=260

All other floppies can be write-protected.

2) In order to perform the installation, you must gain access to the Pro-350 via the printer port. When a cable with pins 8 and 9 shorted together is inserted into the printer port, it puts the Pro-350 into maintenance mode, which is necessary for installing BSD. Either construct a cable, or find an official DEC cable on ebay or someplace (DEC part BCC-08). To construct a cable, use the following pinout:

PC (DB9) Pro-350 Printer Port (DB9)
1 1
2 2
3 3
5-6
7 7
8-9

Once you have a cable, connect it between the printer port of the Pro-350 and the serial port of the PC. Note that while connected via the cable, sending a break signal will put the Pro-350 into the ODT (Online Debugging Tool). If your prompt changes to an @, you are in the ODT. If this happens, hit p to resume.

3) The original notes mention that the Pro-350 expansion cards may need to be in a particular order for the installation to work. I have gotten BSD to install with a slightly different set of cards in a different order, but believe that the DECNA card MUST be in slot 4 (slots are numbered from 0 – 5, left to right) or not present in order for the installation to boot from the hard drive. I do not have a DECNA card to test this theory (I can’t seem to find one), but I originally had a 256KB RAM expansion card in slot 4 and this is the error I received when trying to boot from the hard drive:

m=351232

dc0: addr=1C:0:FF:AA:0:1
ka6=3714
aps=143656
pc=21132 ps=30304
__ovno=5
tt0
panic: trap
sd..done

In order to get by this error, I moved the 256KB RAM expansion card from slot 4 to slot 5. So the order of my cards became:

Slot Card
0 RD51 Controller
1 RX50 Controller
2 Screen Bitmap
3 Extended Screen Bitmap
4 Empty
5 256K RAM Expansion

This worked, but I lost 256KB of memory, presumably because BSD wasn’t using the card in slot 5. So I removed the Extended Screen Bitmap card from slot 3, and put the 256KB RAM expansion in its place. This gave me the additional 256KB of memory that is needed to do anything useful with BSD once the system boots. So the short of all this is to follow the original notes and arrange your cards in the order specified, which is:

Slot Card
0 RD51 Controller
1 RX50 Controller
2 Screen Bitmap
3 256K RAM Expansion
4 DECNA Ethernet Controller
5 Empty?

I’m sure the system can be reconfigured to use a different card order, but for installation, use the above order.

4) When restoring volumes, it is OK if you put the wrong disk in by accident as the system will inform you. If you put the wrong disk in for the first set of a volume, you will receive this error:

Tape is not volume1

If subsequent disks are inserted in the wrong order, you will receive this error:

Wrong tape. Try again
Mount volume x

Installation

Text in italics are actions or comments.  Entries in bold should by typed by the user.

Connect the cable between Pro-350 printer port and PC serial port
Start PC terminal program - use comm settings 9600,N,7,1
Put maintenance0 disk in floppy in drive 0 - make sure it isn't write-protected
Power on Pro350
Until told otherwise, all input is from the terminal, not the Pro-350

40Boot
: r5(0,0)rdfmt format hard disk
Drive type (RD51 - 0 or RD50 - 1) ?0
Format begins...
It takes about 7 minutes to format the drive
Format and bad scan done
Total bad blocks = 0

40Boot
: r5(0,0)unix boot floppy to single user
CONFIGURE SYSTEM:
Couldn't exec /etc/autoconfig
Configuration setup error
Display shows:

mem = 426880

Berkeley UNIX (Rev. 2.9.11) Mon Sep 9 12:28:43 EDT 1985

# /etc/mkfs /dev/rrd0a 2240 create / filesystem
isize = 704
m/n = 5 10

Insert root1 disk in floppy drive 1
# restor rf /dev/rr51 /dev/rrd0a restore / filesystem
Last chance before scribbling on /dev/rrd0a.
Press enter
Mount volume 2
Insert root2 disk in floppy drive 1 - press enter
Mount volume 3
Insert root3 disk in floppy drive 1 - press enter
Mount volume 4
Insert root4 disk in floppy drive 1 - press enter
Mount volume 5
Insert root5 disk in floppy drive 1 - press enter
End of tape

# /etc/fsck /dev/rrd0a verify / filesystem
** Checking /dev/rrd0a
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
172 files 1543 blocks 651 free root1 - root5
or
184 files 1905 blocks 289 free root0 - root5

# /etc/mkfs /dev/rrd0c 6528 create /usr filesystem
isize = 4176
m/n = 5 10

Remove root5 disk from floppy drive 1
Insert usr1 disk in floppy drive 1
# restor rf /dev/rr51 /dev/rrd0c restore /usr filesystem
Last chance before scribbling on /dev/rrd0c.
Press enter
Mount volume 2
Insert usr2 disk in floppy drive 1 - press enter
Mount volume 3
Insert usr3 disk in floppy drive 1 - press enter
End of tape

# /etc/fsck /dev/rrd0c verify /usr filesystem
** Checking /dev/rrd0c
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Free List
200 files 786 blocks 5479 free usr1 - usr3
or
1043 files 4982 blocks 1283 free usr00 - usr15

# sync
# sync
Power off Pro-350
Remove usr3 disk from drive 1 floppy

Power on Pro-350
40Boot
: rd(0,64)unix boot from hard disk

Display shows:

For root1 - root5

m=351872

Berkeley UNIX (Rev. 2.9.54) Thu Nov 14 12:32:20 EST 1985 root1 - root5
or
Berkeley UNIX (Rev. 2.9.55) Tue Dec 10 13:56:37 EST 1985 root0 - root5

CONFIGURE SYSTEM:
rd 0 csr 174000 vector 300 attached
r5 0 csr 174200 vector 310 attached
Erase=^?, kill=^U, intr=^C
#

From this point on, all input is from the Pro-350, not the terminal

# dd if=/rdboot of=/dev/rrd0h count=17 install hard disk boot
17+0 records in
17+0 records out

# passwd root set root password
New password:
Retype new password:

# date 9906201733
Sun Jun 20 17:33:00 EDT 1999

Remove maintenance0 disk from floppy drive 0
Disconnect maintenance cable

# shutdown +1 bring the system to single-user mode
# sync sync the disk
# sync
# reboot reboot the machine

Display shows:

m=351872

Berkeley UNIX (Rev. 2.9.54) Thu Nov 14 12:32:20 EST 1985 root1 - root5
or
Berkeley UNIX (Rev. 2.9.55) Tue Dec 10 13:56:37 EST 1985 root0 - root5

CONFIGURE SYSTEM:
rd 0 csr 174000 vector 300 attached
r5 0 csr 174200 vector 310 attached
Automatic reboot in progress...
Sun Jun 20 17:38:20 EDT 1999
/dev/rd0a: ???
/dev/rd0a: ???
Root was modified-- rebooting.

System reboots

m=351872

Berkeley UNIX (Rev. 2.9.54) Thu Nov 14 12:32:20 EST 1985 root1 - root5
or
Berkeley UNIX (Rev. 2.9.55) Tue Dec 10 13:56:37 EST 1985 root0 - root5

CONFIGURE SYSTEM:
rd 0 csr 174000 vector 300 attached
r5 0 csr 174200 vector 310 attached
Automatic reboot in progress...
Sun Jun 20 17:40:17 EDT 1999
/dev/rd0a:172 files 1543 blocks 651 free
/dev/rrd0c: 200 files 786 blocks 5479 free
Sun Jun 20 17:42:08 EDT 1999
Mounted /usr on /dev/rd0c

Berkeley Unix 2.9BSD

;login: root
Password:

Erase=^?, kill=^U, intr=^C
#

There you have it! BSD 2.9 running on a Pro-350!

Post-Installation

Edit these files as necessary:

/etc/passwd
/etc/hosts
/etc/hosts.equiv
/etc/rc set hostname to match /etc/hosts
/etc/motd
/etc/ttys enable login on tty01 by changing 09tty01 to 19tty01

Note that the F11 key acts as ESC for vi

Installing BSD 2.9 on a DEC Pro-350, Part II – Choosing a distribution

Before I explain the rest of the installation process, I need to explain the haphazard order of the images as distributed in the box#0, box#1 and box#2 directories. The notes on this subject are vague, and to determine the differences myself, I had to perform many installations and comparisons against those installations to figure out exactly what is in each image. Here’s what I discovered.

Maintenance Disks

There are 3 maintenance images – box#0/maintenance0.img, box#0/maintenance1.img, box#2/maintenance2.img. By performing an install with these 3 different images (but keeping the root and user images the same) and capturing the output of “ls -lR /”, I have concluded that all 3 images are identical. If for no other reason than simplicity and consistency, use maintenance0.img for all installs.

Root Disks

In box#0, there are 6 root images – root0.img through root5.img, and in box#2, there are 5 root images – root1.img through root5.img. Again, by installing both of these, I have determined what is different.

The 5 image root set has three files that don’t exist in the 6 image root set:

/.rhosts
/bin/ed
/bin/passwd

The 6 image root set has 12 files that don’t exist in the 5 image root set:

/dev/aaaa
/dev/abc
/etc/rwhod.d
/lib/f77_strings
/lib/f77pass1
/lib/fc1
/lib/libfpsim.a
/lib/libnonfpc.a
/lib/routed
/tmp/Ex00040
/tmp/Ex00043
/tmp/Ex00044

Finally, these files are found in /etc in the 5 image root set, but /lib in the 6 image root set:

ftpd
rexecd
rlogind
rshd
rwhod
telnetd
tftpd

Based on this, I would recommend installing the 5 image root set, as /bin/passwd is essential and /bin/ed will be very useful.

Usr Disks

This one is easy. There are 16 usr images named usr+k??.img between box#1 and box#2, and 3 images named usr?.img in box#2. The difference between these two is explained in the notes – the usr+k??.img images contain the kernel and networking sources. I have verified this by installing both of them. The usr_k??.img images create a /usr/net directory with sources in it, whereas the usr?.img images do not.

Based on the above, if you do not wish to compile the kernel and/or have a limited number of 5.25″ floppy disks, I recommend installing the 3 image usr set. If you have plenty of 5.25″ floppy disks lying around and need to compile the kernel, use the 16 disk set. Note that if you start with the 3 disk set, you can always restore the 16 disk set later (at the price of overwriting the contents of /usr).

So to sum it up, here is what I recommend installing:

box#0/maintenance0.img
box#2/root1.img
box#2/root2.img
box#2/root3.img
box#2/root4.img
box#2/root5.img
box#2/usr1.img
box#2/usr2.img
box#2/usr2.img

That accounts for all the disks, except box#2/unknown.img. The notes say this is supposed to contain the PRO/COMM terminal emulation software, but I’ve tried twice to create this disk and both times all that was there was a lost+found directory.

Now onto Part III – the actual installation.

Installing BSD 2.9 on a DEC Pro-350, Part I – Preliminaries

As a collector of DEC hardware, I recently acquired a couple of Pro-350’s to add to my collection. Now anyone familiar with the Pro-350 probably recalls that the default shipping operating system was P/OS (Professional Operating System), or, as some have been known to call it, the Piece of Sh*t Operating System. P/OS was basically a stripped-down, menu driven version of RSX-11M. The Pro-350 may have shipped with P/OS, but other operating systems were known to run on it as well. Among them are RT-11, Venix, and 2.9BSD.

Assuming you still have access to a DOS machine with a 5.25″ floppy drive and a copy of Teledisk, installing P/OS and Venix on the Pro-350 is trivial. You can find RX50 images for P/OS and Venix here:

ftp://ftp.update.uu.se/pub/professional

or here:

Pro-350 Venix 1.0 TD0 images

The latter includes the proacc.c source code needed to generate the access number needed during installation, as well as a pre-compiled 32-bit Linux binary.

Installing these images to 5.25″ floppies using Teledisk is easy, so I won’t document the process here. You can find Teledisk here:

Teledisk 2.16 for DOS

The problems with P/OS may be many, but for me, lack of a command-line is the real problem. I’ve heard there is a PRO/Toolkit option that gives more functionality, but I’d prefer a more traditional UNIX Operating System. Venix fits the bill, but doesn’t have network support. So the best options for a UNIX Operating System with network support is 2.9 BSD or ProV7M, and the latter is hard to find. I opted to install BSD, as the images are readily available at the Unix Heritage Society site:

http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9-derivatives/2.9bsd4pro350-kcwellsc

Browsing the archive, the first thing you will notice is the site hasn’t been updated for quite some time, and so documentation is lacking. The images themselves aren’t very organized either – you will find what appears to be duplicate copies of some images among the various sub-directories.

The information needed to install these images can be found in the documents sub-directory as a bunch of hand-written notes scanned into TIF images. Reading through the notes, the first thing to do is make/acquire a cable to use for terminal interaction with the Pro-350 from a PC. After that, you need to create a bootable floppy from the maintenance0.rx.50 image. As mentioned in the notes, due to an error in their creation, these images fall slightly short of the size they should be. Fortunately, an acquaintance of mine had corrected versions of these images and those are what I used as the basis for my work. I believe the default images will work, despite being shy a few bytes, but I didn’t try them out. You can find the fixed verisons here:

Pro-350 size corrected BSD images

Now creating the boot disk turned out to be harder than I thought. There are a few places on the web that document how to create an RX50 floppy from linux. One such site is the Xhomer Project Pro-350 emulator site:

http://xhomer.isani.org/xhomer

In the “Reading and Writing RX50 Floppies” section of the site, you will find directions on how to create an RX50 floppy from Linux using the setfdprm utility. Unfortunately, this did not work for me. Every RX50 floppy I created using setfdprm and dd on Linux failed to boot in my Pro-350. I know the procedure works for other folks, but it wasn’t working for me. I tried two machines, one a Pentium 4 class and the other a Pentium I, as well as two Linux distributions – Debian and Slackware. Both failed to create a bootable RX50 floppy.

After a week of messing with floppy creation under Linux, I began to suspect that Linux was the cause of my problems. I say this because I was able to create P/OS and Venix disks under DOS from Teledisk images with no problem, yet I wasn’t able to create a single working floppy under Linux. After some research, I learned about a DOS utility called ImageDisk (http://www.classiccmp.org/dunfield/img/index.htm) which was written as a replacement for Teledisk because Teledisk is no longer supported. Also, ImageDisk claimed to be more robust, with an open-source image format rather than the proprietary format used by Teledisk. So I downloaded ImageDisk and played around with it. Like Teledisk, it could read a floppy and create an image from it, or vice versa. When I learned that ImageDisk would also store the geometry of the floppy disk in the image, an idea occurred to me – why not let ImageDisk create an image file from my bootable Venix disk? That way, I could examine that image with ImageDisk and find out what geometry was used by Teledisk to create the Venix floppy. So I did just that. This is what I learned about the geometry of the Venix image:

300k DD 10 sectors, 512 bytes per sector, read gap = 7, format gap = 14

Now most of these parameters line up with what setfdprm in Linux was set for, except for the gap parameters. In Linux, those values were 20 and 24. Also, my research on RX50 floppies showed the frequency to be 250k, not 300k. So when I created my images with ImageDisk, I had to change those parameters accordingly.

So armed with this new knowledge, I took the BSD maintenance0.img raw image and ran it through the ImageDisk utility BIN2IMD to create an ImageDisk image from a raw binary image. The command to do that is:

BIN2IMD maintenance0.img maint0.imd /1 n=80 dm=4 ss=512 sm=1-10

Basically, /1 means single sided, n=80 means 80 cylinders, dm=4 means 300k, ss=512 means a sector size of 512 and sm=1-10 means create a disk with 10 sectors per track.

Once I had the maint0.imd image, I then used ImageDisk to create a floppy from that image. Before the creation process, I had to change the following settings in ImageDisk:

Sides: One
Double-step: Off
R/W gap: 7
Format gap:14

I then selected write disk from image and the resulting floppy booted in my Pro-350, displaying the 40Boot prompt as documented in page02.tif.

With this knowledge, I think if I were to change the Linux setfdprm parameters to match those of ImageDisk, I could create working RX50 floppies under Linux. The problem is setfdprm is woefully undocumented. From Xhomer and related sites, I have learned that this is the recommended format of the setfdprm string to use for creating RX50 floppies:

Size 800
Sectors per track 10
Heads 1
Tracks 80
Stretch 0
R/W Gap (Gap 1) 0x14
Data Rate 0x01
Stepping Rate (Spec1) 0xdf
Format Gap (Gap 2) 0x18

Clearly R/W Gap and Format Gap map to the same values in ImageDisk, but I’m not sure what the Stretch, Data Rate and Stepping Rate values map to, nor do I know how to specify the frequency. I’m sure with the right values, I could create a usable floppy under Linux. What’s strange is how these values must have worked for those who published the information, but not for me.

That’s it for this post – stay tuned for Part II, where I demystify the various images in the 2.9 BSD distribution.