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:

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:

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

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
# syncPower 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:

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.

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:

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.

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:

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:

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:

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:

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:

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).

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.

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:

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:

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:

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:

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:

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:

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.

All of a sudden, my NetBSD 6.1.2 SPARC NFS client failed to mount my FreeNAS share with this error:

mount_nfs: rpcbind to nfs on server: RPC: Program not registered

The only thing that recently changed was I upgraded my FreeNAS server from 8.3 to 9.2. Since several of my other NFS clients were able to connect to the share, I was doubtful the upgrade was the problem.

After a lot of digging, the problem turned out that I now needed to mount the share with the TCP option. So adding tcp as an option to my /etc/fstab fixed the problem.

nas:/mnt/volume1/backup /backup nfs tcp,rw 0 0

Based on this, I can only conclude some default changed in FreeNAS that forced me to have to add the tcp option to my NetBSD box.

The Intel SS4200 is capable of serving quite nicely as a home NAS. It’s compact design, low-power consumption and quietness make it ideal for the home user. Now add FreeNAS to the mix and you’ve got yourself a robust home NAS solution. I must stress the word “home”, as its use in a commercial environment would be severely constrained by the SS4200’s 2GB memory limit, especially if you plan on using ZFS. Note that the 2GB memory limit is a hardware constraint – there is nothing you can do to overcome it. In order to use 4GB, a second memory slot would have to exist on the motherboard, and no such slot exists (probably a cost saving measure). Installing a 4GB memory stick into the one and only slot causes the unit to fail to boot, so the best you can do is install a 2GB DIMM in the one slot. The CPU, on the other hand, can be upgraded to at least an Intel Core2 Duo 4400 running at 2.00GHz. The unit is also capable of handling four 4TB drives, yielding up to 16TB of storage (assuming no redundancy).

The SS4200-E (and the re-branded Fujitsu-Siemens Scaleo Home Server) contain an IDE slot with a DOM (Disk On Module) that, with a little money and effort, can be used to install FreeNAS rather than the default EMC NAS software that ships with the unit. Note that the SS4200-EHW does not contain a DOM, but it does have an empty IDE slot in which a DOM can be installed. So these instructions apply equally well to all models.

The first thing you will need to do is get yourself a new DOM, as the unit ships with a 256MB DOM which is not big enough for FreeNAS. For FreeNAS versions earlier than 9.3, a 2GB DOM will suffice. For FreeNAS versions 9.3 and greater, you will need a minimum of a 4GB DOM, though 8GB is recommended. You should be able to pick one of these up on ebay for around $25. If you shop around, you will find 4GB, 8GB and 16GB DOM’s for roughly the same price, so you might as well go for an 8GB (or greater) unit. Be careful to order a 40 pin version, as 44 pins will not fit. You will probably also want a vertical model, as a horizontal one may not fit in the case.

What you read here is basically a rehash of information I have found on the net, particularly from the pbworks site at http://ss4200.pbworks.com and the FreeNAS site (http://www.freenas.org). You will find detailed information for most everything you read here on those sites. I have just consolidated what I have learned from them, along with my experiences, here.

Once you have the proper size DOM, you will also need a USB flash drive of at least the same size as the DOM and a copy of the FreeNAS software you wish to install. You will also need a computer with a USB port and a free IDE slot. I highly recommend you have console access to the SS4200, either via the serial port or a video card. In fact, I’m not sure you can proceed without it as my experiences have shown that the SS4200 defaults to booting from the SATA drives by default which is not what we want. So you need to be able to enter the BIOS and change the default boot device from SATA to the DOM. Even if your BIOS is currently set to boot from the DOM, I have seen it default back to SATA after an install. Instructions for using the serial port or video card can be found on the pbworks site mentioned above. Note that the installation process I describe here is for Linux, though any operating system that can run FreeNAS should work, assuming you can find comparable tools (basically, a dd substitute).

Now that the prerequisites are out of the way, install FreeNAS to the USB stick as described in the FreeNAS instructions. For example, here is how to install FreeNAS 9.2.1.9 to a USB drive attached to /dev/sdc. CAUTION: do not use /dev/sdc unless that is truly your USB device – this is just an example. Using dd in this way will destroy all data on the specified device, so be sure to use the correct device. There are several ways to determine your USB device, such as watching the output of dmesg when you plug in your USB drive. If you are unsure of your device, search the web for information on how to do this for your operating system. Note that you will probably need to be root to execute this command.

For an image file, use this command:

xzcat FreeNAS-9.2.1.9-RELEASE-x64.img.xz | dd of=/dev/sdc bs=64k

For an iso, use this command:

dd if=FreeNAS-9.2.1.9-RELEASE-x64.iso of=/dev/sdc bs=64k

If all goes well, FreeNAS is now installed on your USB drive. Unmount the USB drive, power off your system and install the DOM in an empty IDE slot. When finished, power on your machine and boot from the FreeNAS USB drive. Note that you may have to tell your BIOS to boot from the USB device rather than your system disk.

If done correctly, your machine should boot into FreeNAS and present you with an installation menu. Go ahead and select the Install option, and then select the DOM device as the target. Be sure to remember the name of this device (it should be something along the lines of /dev/da4). CAUTION: once again, you need to be sure to select the correct device, the DOM, as the target and not one of your system disks, else data loss will occur. If unsure, do not proceed – cancel the installation and consult the FreeNAS documentation. If all else fails, a nearly foolproof way to proceed is to power off your system and disconnect all storage devices. That way, when you boot into FreeNAS the only storage devices shown will be the DOM and the USB drive you booted from. And if you accidentally choose the USB device, no real harm is done (though you will need to re-install FreeNAS to the USB drive and restart this procedure).

Installation from the USB drive to the DOM will take some time, as the DOM isn’t the fastest device on the planet. Plan on it taking at least 20 minutes. Once done. do NOT reboot the system – instead, choose shell from the menu. As described on the pbworks site, the SS4200 will not boot from the DOM without modifying some parameters in the FreeNAS /boot/device.hints file. So we will modify that file now. If you somehow already rebooted the machine, you can always enter the shell from the installation menu.

From the shell, you will need to mount the root partition of the DOM. If you recall, I asked you to remember the DOM device above. In this example, that device is /dev/da4. If you’ve forgotten the device, all is not lost, but you will need to do a little investigation to find the device – doing an ls in /dev should help. Once you know the device, you will need to find the root partition to mount. For the installations I have done, the root partition has been s1a, though I can’t say this will always be true. If s1a is not your root partition, you will have to do some digging by mounting and unmounting partitions until you find the root partition. Once you find a partition with /boot, you’re in the right place. You can mount the partition with the following command:

mount /dev/da4s1a /mnt

With the root partition mounted, edit the /boot/device.hints file:

vi /mnt/boot/device.hints

And add the following lines to the end:

hint.ata.0.at=”isa”
hint.ata.0.port=”0x1F0″
hint.ata.0.irq=”14″

As described on pbworks, these lines allow FreeNAS to recognize the DOM. Without them, FreeNAS fails to find a boot device and so can’t continue the boot process.

After editing device.hints, save the file and unmount the partition:

umount /mnt

At this point, you now have FreeNAS installed on the DOM with a modified device.hints file that will allow you to boot from the DOM. Exit the installation, power off your system and remove the DOM. We are now through with this system, so you can put it back to its regular use.

Next, install the DOM into the SS4200 and power it on. Hopefully, you have video or serial console access to your SS4200 and can watch it boot. If so, you should see the boot sequence proceed normally and eventually seem to hang at this line:

Waiting up to 5 seconds for ixdiagnose to finish... done.

At this point, it seems the system is hung, but if you wait 5 or 10 minutes, it will eventually free itself and continue booting. All I can figure is FreeNAS is configuring itself for first-time use and needs a bit of time to do so. If you hit the web address assigned to FreeNAS from your browser (you can get this address by scrolling through the output of the boot process), when the installation is finished the FreeNAS GUI will start and prompt you to enter a root password for the system.

If your system fails to boot at all, be sure to check the BIOS and ensure that it’s booting from the DOM device and not the SATA drives. If it partially boots but drops you to a mountroot> prompt with an error similar to:

Mounting from ufs:/dev/ada0s1a failed with error 19

Your edits to device.hints may be incorrect. If so, you will need to mount the root partition of the DOM and try again. You can do this by putting the DOM back into your Linux box, booting from USB drive and selecting the shell option from the menu. Of course, you could also mount the partition directly from Linux if everything is setup correctly, but since you have to reboot the machine anyway to insert the DOM, booting FreeNAS is just as easy.

If all goes well, you should now have FreeNAS running from a DOM on your SS4200!

With the port from Linux to BSD done, I now returned to the OS X port. My thinking that porting from BSD to OS X would be easier than porting from Linux to OS X turned out to be true, but there were still unforeseen obstacles to come.

The first obstacle I ran into was my game timer wasn’t working on OS X. On Linux and BSD, I was using the sigaction and setitimer system calls to implement a timer that would execute a timer_service routine via SIGALRM once per second. Unfortunately, this mechanism wasn’t working on OS X, and I wasn’t sure which syscall was in error – sigaction or setitimer, since both were needed to implement the timer. My gut feeling (and experience) told me it was sigaction, but I wasn’t 100% sure. I’ve run into problems with sigaction in the past (including during the BSD port) and the problem usually turns out to be finding the right sigaction struct to use. While researching this, I learned something I did not know about OS X – it requires the stack to be aligned on 16-byte boundaries when making external calls. I thought this might be the issue, so I made sure to align the stack, but it didn’t help. I spent a lot of time looking into this, even posting the following question on Stack Overflow:

Unfortunately, as of yet, there have been no answers to my question. While waiting for an answer, I discovered that the OS X library function, _sigaction(), did work. Of course, this requires me to link against libc, but while I research the problem and/or wait for an answer, it will allow me to continue work on the port. I’m curious why the other syscalls I’m using work (open, read, write, etc.), but sigaction doesn’t. One thing I noticed is that the disassembly of _sigaction() is quite lengthy compared to other system calls, leading me to believe the library call is doing something extra.

With the sigaction problem solved for the moment, I next had to focus on the 16-byte alignment issue. Most of the reading I did on this subject turned out to be false, causing me to waste enormous amounts of time. For example, I read that OS X would start your program with the stack already 16-bit aligned and that the stack needed to be aligned on a 0xXXXXXX0c boundary at the point of the syscall. Both of these turned out to be false. Initially, my program kept crashing randomly upon startup. I discovered this problem while debugging, when I noticed the starting address of the stack in _start was always 4-byte aligned, but only 1/4 of the time was 16-byte aligned. I solved this problem by adding code to align the stack to 16-bytes upon start-up. As for being aligned at 0xXXXXXX0c before a call, it turns out it needs to be aligned on 0xXXXXXX00.

With the start-up problem out of the way, I focused on aligning the stack on all routines that made external calls (system calls, in the case of Madness) on a 16-byte boundary. This proved to be harder than it sounds and turned out to be very time-consuming. Again, the documentation on this subject led me astray. Supposedly there are two options, -mstackrealign and -mstack-alignment=16, that can be used to solve this problem. Unfortunately, they don’t appear to work. The clang compiler accepts them, but they don’t seem to align the stack. I have a suspicion that these arguments, as well as the guarantee that the stack starts out 16-bit aligned, only applies when writing C code and not assembly.

As if the above problems weren’t enough, I learned that the lldb debugger that I was using was reporting the esp address incorrectly. I aligned all my code by single-stepping through the debugger, but in the end the code still didn’t work. When I substituted printing the esp via the code, I noticed the values were different (usually off by 8). I believe using the debugger skews the stack pointer, and so should not be used to help manually align the stack. After discovering this, I had to go back and realign the stack on all routines that made syscalls.

Another oddity I discovered with the lldb debugger was using it remotely through a terminal. For most of the OS X work, I used OS X Mavericks on my Hackintosh (which I created using the excellent utilities and tutorials over at tonymacx86 http://www.tonymacx86.com). As I started to port to more operating systems, it made sense to me to instead virtualize OS X and stick the VM on one of my servers, just like I was doing with FreeBSD. That way I could free up my laptop to run Linux and ssh into all the various platforms needed to develop Madness. So I created a Snow Leopard VM under Virtual Box, using the same utilities from tonymacx86. I had to start with Snow Leopard for two reasons:

1) VirtualBox doesn’t support booting from USB, so I needed OS X to be on a DVD.
2) The only DVD of OS X I have is for Snow Leopard, and the iBoot (http://www.tonymacx86.com/downloads.php?do=cat&id=3) software doesn’t seem to support booting itself from CD and then installing OS X from USB. As far as I could tell, both iBoot and OS X either need to reside on disc or USB – you cannot have one on CD and the other on USB.

Once Snow Leopard was installed, I upgraded it to OS X Lion using the xMove Lion utility (http://www.tonymacx86.com/downloads.php?do=cat&id=9). Once on Lion, I upgraded to OS X Mountain Lion, using xMove Mountain Lion. There doesn’t seem to be an xMove for Mavericks, so my VM is currently stuck at Mountain Lion. All of this worked fine, but when I tried to use lldb remotely through ssh it kept exiting with one of these errors:

When I ran lldb locally on the VM, it prompted me for my credentials. After digging around, it turns out I had to enable security by running this command directly on the OS X VM (not through ssh):

/usr/sbin/DevToolsSecurity -enable on

Once I did that, I was able to use lldb remotely for debugging.

With all these problems out of the way, Madness on OS X is now a reality. The code seems to work, but I won’t swear that I’ve found and aligned all possible areas where the stack needs to be aligned on 16-bytes. To make tracking this easy, I put in a check for an unaligned stack on OS X only. If the code detects an unaligned stack, it will print an error message and exit.

Forgetting about the not-so-successful OS X port for the moment, I started work on a BSD port. I like BSD and so happen to have two BSD machines available, but one is running FreeNAS and the other is running NetBSD on SPARC. The FreeNAS box doesn’t have the GNU toolchain installed by default, nor did I wish to install it since I use it for storage only. The NetBSD box is a totally different architecture, so it is out of the question. I do have an old x86 box somewhere running NetBSD, but rather than fire it up I instead opted to use a FreeBSD 9.1 VM I had lying around for such occasions.

Unlike OS X, I expected the BSD port to be relatively easy. For the most part, that turned out to be true. Like OS X, I knew I had to change the system call mechanism from passing arguments in registers to using the stack. The one snag I hit was BSD requires 4-bytes of spill space after all parameters are pushed onto the stack, but before the system call is made. The FreeBSD Developers’ Handbook has information on this (http://www.freebsd.org/doc/en/books/developers-handbook/book.html#x86-system-calls). To make things simple, the handbook recommends wrapping the int 0x80 call in a wrapper routine to avoid having to deal with the 4-byte spill area.

After modifying the hardware.s module to pass arguments via the stack (most of which I had done previously in the OS X port attempt), FreeBSD mostly worked. The biggest problem I ran into was using sigaction. In absence of being able to register interrupts like you could on the 6809, the Linux port uses sigaction and setitimer to implement a game timer to control things such as creature movements. For some reason, on BSD, the timer wasn’t working. After a lot of digging, I discovered that there are three BSD sigaction system calls – 0x2e 0x156, and 0x1a0. I was originally using 0x2e, which didn’t work. Once I switched over to using 0x1a0, the timer routine started working. The difference between the system calls is 0x2e and 0x156 are for compatibility and compatibility 4, respectively, each of which require a #define to be set. The 0x1a0 system call is standard and so is always available. With this change in place, only a few more code changes were required, most of which were just oversights from the Linux port that BSD detected (for example, using the full eax register value rather than just al).