Thursday, May 29, 2014

Retrocomputing with Solaris 2.5.1 x86


Versions of Solaris x86 prior to 7 are a little difficult to come by. Yeah, I'm sure you can download them from somewhere, but that's not really my style. I guess I should say that physical media is hard to come by.


A while back I came by some.

solaris 2.5.1 - 1. packaging

eBay to the rescue yet again.

Man, that's some fancy packaging.

Unfortunately it languished in my closet for weeks before I had any time to give it a run. Actually I had a hurdle to jump too. The installer boot media is a floppy and I didn't have a floppy drive. Microcenter had one floppy drive in the entire store but it was an internal. I'd have bought it but my motherboard doesn't even have floppy controller on it. What modern board does? USB was my only hope. I'd borrowed a USB drive from the shop down the road last time, but not wanting to make a nuisance of myself, I declined to bother them again, and just ordered one of those off of eBay too. Then I took a little vacation... All of that took weeks.

But, a few days ago I had an opportunity. It wasn't exactly free time, but the project I'm working on right now regularly requires that you let it run for 3-5 minutes and wait for it to finish. So, in those 3-5 minute blocks, I managed to get Solaris 2.5.1 running in VMware.

"How?" you might ask.

Like this...

VM Configuration

Solaris 2.5.1 has two fairly significant limitations that took me quite a bit of trial and error to discover. The biggest hard drive that it supports is somewhere between 1G and 2G, and though it supports PCNet ethernet cards, it doesn't recognize VMware's emulated PCNet card. Actually, the boot disk does, but Solaris itself doesn't. Go figure.

I ultimately ended up configuring the VM with 128m of ram, three 2G hard disks, no sound card and no ethernet card. I also made sure that the first disk was on IDE 0:0, second on IDE 0:1, cdrom on IDE 1:0 and third disk on IDE 1:1. Rather than installing directly from the media, I made backup images of the CD's and boot floppy, aimed the cdrom at the "Software" CD image and aimed the floppy at the boot floppy image.

I did want some kind of networking, so I added a serial port, using a named pipe and made "this end" the client and "the other end" a virtual machine. More about that later though...

Why not just use Qemu or Bochs, whose NICs might be recognizable? I tried both. Neither were able to run the installer from the CD. I tried lots of different configurations - IDE, SCSI, converting the cdrom to a hard disk image, etc. Nothing worked.


At any rate...

The installer was similar to Solaris 7 but a bit more primitive. That's one of the things that I love about tinkering with old OS'es though. It's fun to watch the evolution of systems, even in reverse.

Most of the prompts were intuitive. The installer asked for precious little networking info, only the host name actually. I bypassed Graphics Device configuration as I usually do with Solaris installations. The date defaulted to 1911 and upon seeing that, I wondered what Y2K bugs I'd run into later. I selected a Standalone system type and installed the Entire Distribution.

Disk partitioning was a little tricky. I was presented with all 3 disks and one-by-one, chose to Auto-layout Solaris Partitions. This created a 1858mb partition on each disk. I also chose to Auto-layout File Systems and unchecked /usr and /opt.

On the File System and Disk Layout screen, I was presented with 3 partitions: c0d0 contained root and /export/home filesystems, c0d1 had /export/home0 and c0d1 had /export/home1. Though each partition was about 1.6G, the file systems only used about 1G of that and I was unable to make them larger - something about a 1023 cylinder limit. Between the 3 disks, I had about 3G of space though, which ought to be plenty.

I planned on building software in my home directory under /export/home and installing it under /opt/sfw, so I did rename the partitions. On c0d0 I removed /export/home altogether and changed the root to 876mb (or 876 blocks or cylinders, or whatever units the partition manager used). On c0d1, I renamed /export/home0 to just plain /export/home. On c1d1, I renamed /export/home1 to /opt.

This gave me 1 filesystem per partition and about 1G of space in each filesystem.

It's funny, disk space these days isn't unlimited, but for the purposes of downloading, building and installing software, it might as well be. Long gone are the days where you have to think hard about how to layout your disks so you don't run out of space building software. Playing with Solaris 2.5.1 brought all of that back though.

I told the installer not to worry about remote file systems and not to automatically reboot. If something went wrong, I wanted to see it on the screen, not discover it way later after an auto-reboot.

And, voila!

solaris 2.5.1 - 2. install


The install went smoothly. The first boot required a little post-install configuration, like selecting the keyboard layout and entering a root password. I bypassed Graphics Devices again.

Aside from some safe-to-ignore CD-related error messages, the system came up cleanly and gave me a login.

solaris 2.5.1 - 3. boot


I added a user for myself, created /usr/local and /opt/sfw directories and tweaked everyone's path in /etc/profile:


Everything was running smoothly.


I needed to get some kind of networking going though.

This was not quick and easy by any stretch. I spent hours fiddling with configuration files, manually loading kernel modules, applying and re-applying patches... Nothing. The PCNet NIC was unidentifiable and e1000 was even more hopeless. I'm not saying that it's impossible to get it to work, but I couldn't figure out how. In the end, I resorted to PPP.

There are a lot of links on the web pointing to Solaris PPP configuration tutorials, but almost all of them are dead. I did find one though, and between it, man pages and comments in various files, I extrapolated out the following, working PPP configuration.

On the solaris VM, I mentioned earlier that I set up a serial port to a named pipe, with "this end" the client and "the other end" a VM. On a separate Linux VM, I also added a serial port to the same named pipe, with "this end" the server and "the other end" a VM. It's important that one end be the sever and the other the client. Declaring both ends the server causes VMware to complain at boot that another VM is holding the pipe. I assume the same would be true if both ends were declared to be the client, but I didn't test that.

On the Solaris VM, I configured the following files, in the following ways:

/etc/hosts solaris251-ppp solaris251

solaris251 is the local host name and is the local IP. solaris251-ppp is the other end of the PPP connection and will have address Solaris' PPP requires these host file entries. Leaving them out creates difficult-to-debug errors.


ifconfig ipdptp0 plumb solaris251 solaris251-ppp up
interface ipdptp0
peer_system_name solaris251-ppp
inactivity_timeout 0

This configures a network interface named ipdptp0 with the IP for "solaris251" on this end and the IP for "solaris251-ppp" on the other end. Solaris PPP leans heavily on UUCP for actually connecting between systems. As such, the peer_system_name directive tells PPP to use the UUCP definition for "solaris251-ppp". The inactivity_timeout directive of 0 tells PPP not to close the link due to inactivity.


solaris251-ppp Any Direct 115200 - -

Now we're delving into deeper magic. UUCP! Anyone remember that? Fortunately the Solaris UUCP config files are pretty thoroughly commented. This line defines a system named "solaris251-ppp" that can be connected to at Any time of day, using the Direct dialer, at 115200 baud with no phone number (the first -) and no login script (the second -).


Direct cua/a - Any direct

Even deeper magic. This line defines a dialer named Direct that uses serial port cua/a. I'm not sure what the - or Any mean in this file but "direct" means to use the a device named "direct" from the Devices file. This line actually already existed in the Dialers file, but used cua/b (the second serial port) rather than cua/a. I just updated it to use cua/a. I found it odd that it would default to the second port rather than the first. I'm sure it was conventional to have something else on the first port back in the 90's, but what that might have been is lost to history.

The /etc/uucp/Devices file defines configurations for modems or direct serial cable interfaces. It already had a "direct" device definition and I didn't modify it.




hosts: files dns

I just updated that one line.


I also added an init script to ping the remote system and cause the ppp connection to come up. It's possible that there's some directive that I could have added to to make the connection come up, but I couldn't figure it out.



case "$1" in
/usr/sbin/ping solaris251-ppp > /dev/null 2>&1
echo $"Usage: $0 {start|stop}"
exit 1

exit 0

And to make it actually run at boot...

chmod 755 /etc/init.d/pppup
cd /etc/rc3.d
ln -s ../init.d/pppup S90pppup

All that was just on the Solaris side. The other end of the ppp connection, on the Linux machine, had to be configured too. This was fortunately a lot simpler. All I had to do there was add an init script.


#! /bin/bash

# See how we were called.
case "$1" in

# pppd for solaris 2.5.1
/sbin/pppd noauth crtscts lock passive persist proxyarp ktune /dev/ttyS0 115200
# kill pppds
killall pppd

# disable ip forwarding
echo 0 > /proc/sys/net/ipv4/ip_forward
$0 stop
$0 start
echo $"Usage: $0 {start|stop|restart}"
exit 2

exit $rc

The pppd options are all very important. "noauth" means the Solaris VM doesn't have to to PAP/CHAP authentication. "crtscts" sets up flow control. "lock" establishes a lock file so accidentally starting another pppd won't wreak havoc. "passive" tells pppd to wait for connections rather than giving up and exiting if it can't establish one itself. "persist" means not to exit if the other end closes its connection. "ktune" causes pppd to enable IP forwarding. I could have done that manually but it was an option, so I used it.

The "proxyarp" option is very important and also hard to explain. It causes pppd to add an ARP entry containing the hardware address of the local ethernet card and the IP address of the Solaris machine. This makes it appear that the Solaris VM is on the local network, even though technically it is sitting behind the Linux VM. Packets destined for the Solaris VM will be routed to the Linux VM. Once they're on the Linux VM, they'll be routed to the Solaris machine via local routing rules. It's kind of a hack, but it obviates the need for NAT and connection tracking.

I set up the PPP server to run at boot too:

chmod 755 /etc/init.d/pppserver
cd /etc/rc3.d
ln -s ../init.d/pppserver S99pppserver

There is probably some more official way to configure PPP that would cause it to come up automatically without the need for the init script, but this way seemed easier and more portable, and at the time I just wanted to get it working quickly.

So. After all that, and after recovering from a little misconfiguration. I ran the init script on Linux, rebooted Solaris and BAM! Networking!

I could ping yahoo. I could telnet all over the place. I could ftp to

solaris 2.5.1 - 4. networking

I was really happy until I remembered that it was running at 115200 baud. The actual throughput was around 3 kilobit. Downloading software from GNU took minutes. The setup was ok for telnetting into the Solaris system, but it was infinitely faster to transfer files by making an ISO image of them, aiming VMware's fake cdrom at the image and copying them off.

I tried higher baud rates but I couldn't get anything working higher than 115200. There might be some way, but I couldn't figure it out.


Oh well. It was still fun to get it all working.


Software for Solaris 2.5.1 is outright impossible to find. If that's an exaggeration, it's only a slight one. I ended up building everything I needed from source, just as I'd done on Solaris 7. I even used the same versions of software.

To summarize...

On my Solaris 7 VM, I built a version of gcc that runs on Solaris 2.5.1 and build software for Solaris 2.5.1:

./configure --prefix=/usr/local/gcc-2.95.3 --host=i386-pc-solaris2.5.1 --target=i386-pc-solaris2.5.1 --enable-shared
gmake install

(I probably could have build gcc for 2.5.1 on any version of Solaris, not just 7, but I was pulling other software off of that VM at the time, so I used it to build gcc too.)

Then tarred it up and copied it over to Solaris 2.5.1 and used it to build gzip and rebuild gcc, both of which I installed under /opt/sfw. Rebulding gcc required that I set CC=gcc during the configure step...

CC=gcc ./configure --prefix=/opt/sfw --enable-shared

...but otherwise went smoothly.

I added /opt/sfw/bin to everyone's PATH and /opt/sfw/lib to everyone's LD_LIBRARY_PATH and everything else was downhill from there.

I built and installed bash, sudo, perl, openssl, zlib and openssh. None of the manual tweaks that I'd applied when building on Solaris 7 were necessary though I did have to specify --without-pam when configuring sudo. I set up ssh to run at boot just as I had on Solaris 7, and was soon able to ssh into the VM.

solaris 2.5.1 - 5. ssh

I also built gnu tar, lynx, wget, cvs, make and vim. I couldn't get apache 2.0.65 to build though. The configure script stalls out during a TCP_NODELAY test. Maybe an older or newer version will work though. I have yet to try it out. Netscape 4.78 for Solaris 2.5.1 x86 was also a failure. Though the filename alleges Solaris 2.5.1 support, it appears to require a newer version of libresolv than the default installation comes with. Perhaps some patch will fix that. I didn't look too hard for that.


Getting a graphical environment working was also difficult and disappointing.

The default installation comes with the openlook windowing system. I ran kdmconfig -c and followed the intuitive prompts but all I could get was 16 colors at 640x480.

solaris 2.5.1 - 6. openwin

Cute, but not all that impressive.

I'd had the same issue with Solaris 7 though, and installed XFree86 4.7.0 to resolve it. Unfortunately the same solution wasn't all that workable on 2.5.1. I tried installing every version of XFree86 from 3.3.6 to 4.7.0. The 4.X series all fail because __ctype_mask, snprintf and vsnprintf are undefined on Solaris 2.5.1. After some monumental hackery, I was eventually able to get the X server from 4.7.0 to run as root but the system wasn't generally workable. 3.3.6 installed cleanly but its SVGA driver didn't work with VMware. I may eventually get decent graphics working, but doing so will be enough for its own article.

CDE comes on a second CD with the Solaris 2.5.1 distribution and I installed it.

cd /cdrom/cdrom0
cd CDE/x86
sudo ./install-cde

The installer is semi-intuitive and you have to reboot afterwards. CDE worked but it looked terrible in 16 colors and all I used it for was to log in, run a terminal and disable dtlogin.

dtlogin -e

The ultimate goal of all of this is, of course, to get a development platform working.

I had enough for that, and with a few small tweaks my software built and ran. As was the case on Solaris 7, I wasn't able to get any database software to build and I had to disable openssl support because for some reason, the version of openssl that I've been using only builds static libraries on Solaris platforms.

But I was able to run the client-side and access Oracle 12c.

solaris 2.5.1 - 7. sqlr

Again, not so impressive, as Oracle did at one point release software for Solaris 2.5.1, but it's also difficult to come by these days. I did see version 7.3.4 on eBay a while back for Sparc Solaris 2.X and I think a few copies of 8.0.5 for Sparc Solaris are out there right now, but being for Sparc platforms, those don't really do me a lot of good.

Other Software

The distribution came with a second CD containing CDE, WABI and ODBC. I installed CDE but without decent graphics, it wasn't much to write about. WABI would no-doubt be equally drab without good graphics so I didn't even bother to install it. If I can get some good graphics going I'll write another article about that. I guess I could try out ODBC. I'm curious if it comes with any drivers.

Fuel for future writing.


...or endearing features as I prefer to call them.

  • Supports 1.8g partitions but only uses 1g of that space.
  • You have to use the Delete key to Backspace.
  • The default shell doesn't understand ~/ but does understand $HOME.
  • Filesystem performance is not so good, untarring and rm -rf'ing take a while.
  • Setting the domain in /etc/resolv.conf uses the domainname keyword rather than domain.
  • The CPU doesn't idle, so running it as a VM slams the host OS's CPU
  • libc contains working versions of __snprintf and __vsnprintf but they aren't defined in the header files.

Ok, so that was kind-of fun, especially PPP. I wish I'd been able to get the web stuff and better graphics working though. The web stuff probably won't take too much work.

Graphics though... Hmm... Maybe someday.