I’ve wanted a NeXTCube since I first learned what they were, which was well after they stopped being made, and some time after Apple bought NeXT. Last summer, I finally got one as Dan Messing decided he didn’t want to lug his out to Portland in his move. It was a physical machine, but not much more than that. It couldn’t boot. It couldn’t even power on. But hey… it had that awesome little logo on every component, and that was a hell of a start.
Powering On
I can’t speak for all NeXT hardware, but the cube was built so that the display would connect to the cube, then the keyboard, mouse and audio would connect through the display. There’s no physical power button on the cube, the button is on the keyboard. This cube came without the cable that connects the display to the cube. I did some research online, and considered building the cable myself. Decided that since I’m no electrical engineer, and I could manage some damage if I screwed up pins, that it’d be a better idea to just find one somewhere I could buy. There’s a company in the US, Black Hole Inc, that actually sells NeXT equipment, so I ordered one from there.
I got the cable a few weeks later, connected it all together and hit the power button. Fans turned on, the screen lit up, it beeped. I smiled. It spat out an error about the SCSI disk, which Dan told me had gone bad. Attempts at booting went nowhere. Well, at least I can look at the NeXT boot rom, right? The fact that they made that look like their Terminal app is awesome.
Screw that, I didn’t get a cube to just stare at its boot rom. Let’s get this thing up and running! What do I need? Well… something to install the operating system onto would be a good start. And a way to install said operating system would be another requirement. I figured I could likely find ISOs of OPENSTEP install media online, but as it turned out, Chris Dandeneau had an original box of it from when IDFusion used to be a WebObjects company and Apple was dumping inventory. I took a trip to ye olde computer shop that I knew sold antiquated computer equipment and bought a 2gb SCSI-2 hardware along with a SCSI cdrom.
Threw them in there, which was tricker than expected since it wasn’t designed for either 3.5inch harddrives (it came from the days of 5.25inch HDs), nor CDROMs at all. Its front face only really supports that bizarro Magneto-Optical thing the original cubes came with. Let’s just say the CDROM hung out outside. I’m all set, I thought. Once the OS is installed, I don’t really need the CDROM anymore, so it doesn’t matter that it’s a ghetto setup. Well… yeah… no. As it turns out, though SOME NeXT machines could boot off of CDROM, this wasn’t one of them. I wasn’t able to find a floppy drive that was compatible with it, either. I needed something to jumpstart the install process… you know, actually boot the thing.
…I said Boot!
I looked at my options, and realized my best bet was to do a netboot. Every NeXT machine came standard with a network interface. Luckily for me, the cube I have was the first one to have that be “standard ethernet” as opposed to coax (token-ring, I guess?). Unluckily for me, I knew nothing about netbooting other than the fact that it was this cool thing I’ve always wanted to do back when I was a Linux user, but never had hardware capable of it.
I spent a few nights with OS X’s DHCP services, since it’s capable of netbooting other Macs. I never got anywhere with that. I installed NetBSD’s DHCPd on OS X and tried with that. I got to the point of getting an IP over to the cube, but it never did anything beyond that. I knew too little, and was rushed due to our move to Ottawa. I put it aside and said I’d try again when things settled down again.
It took a while for things to settle down. The move, new job, a few conferences, christmas… Some time in February I finally managed to drag it out from the box it was in, and start toying around again.
This time I was smarter: screw OS X as a netbooting host. I know next to nothing about OS X’s network services, but I used to be a sysadmin at an ISP that ran Linux for everything. I setup a Debian virtual machine whose network adapter was bridged with my Mac’s ethernet port. A nice bonus of using Linux was that it actually has read support for the NeXT flavor of UFS they used for the filesystem on the OPENSTEP install media.
It actually didn’t take me that long to get it netbooting from there. It was super interesting to watch tcpdump during the whole process to see what was going on. The trickiest part being setting up the TFTP server for some reason. You need a surprising number of services to netboot the thing: dhcpd, bootparamd, tftpd, nfsd, and dns. I hate bind configuration files. NFS not wanting to serve up the CDROM mount point was also an annoyance, but nothing a little cp -A couldn’t fix.
It could now boot into the installer, from the network. My original plan was just to get it to load the kernel to get it to see the CDROM and do the install that way. The fact that I could now just serve up the whole installer from the network was a huge bonus.
Install where, you say?!
I’m all set, right? Installer can start up, I should be up and running in no time. Well… you see… here’s where I learned that somewhere between packaging the cube up before the move and now, I lost the harddrive I bought. Cause you know… I didn’t have enough trouble.
Plow ahead! A this point I knew more than I’ve ever wanted to know about netbooting, and I’ve been reading from others who permanently run their NeXT boxes purely from the network once the harddrive died. Not a bad idea, why would I want to depend on some old drive? When it dies, I have to go through all of this again? No thanks.
New plan : Let’s setup two NFS shares, one that serves up the installer, and the other that I’ll install it to. Slight wrinkle in that plan : The OPENSTEP installer A) fails when it can’t find a harddrive in the machine, and B) doesn’t support installing to an NFS mount (don’t really blame it there).
Interestingly, the entire installer process is a single shell script, the init process checks for its presence, and runs it if it’s there. A shell script. To install an operating system. Think about that for a second. Even better, it asks about 4 questions then runs: “ditto -arch some_arch -bom somebom / /install_mount”. So…comment out the parts that look for a disk, mount the NFS share, hardcode it to ditto over there and I’m golden.
Well not quite. Cause to get the critical parts to actually work out, I had to edit the install script, and the CDROM’s /etc/fstab. /etc/fstab is one of the files that’s in the BOM list, so it gets copied over. Part of a BOM file is a checksum, and if the checksums don’t match, the whole ditto process fails. So I was getting to the point of copying /etc/, and things would go south. I considered rebuilding my own BOM file, but it seems like that format has changed between then and now (where I have tools for it). I couldn’t just remove the -bom option because then it’d copy the whole CD. I can do that with cp. Obviously it was omitting some files (like the installer script) that would indicate that it should boot as a live system.
I ended up using my Mac to run ditto -arch from one share to another, and moved over the installer manually. When doing that and booting off of the new share, it actually got pretty far into the start up process. It actually got to the point of loading the window server, and I could telnet in, but it seemed stuck in a loop. Looking at log files it seemed stuck running BuildDisk. I’m in over my head. WTF is BuildDisk? I signed up for what’s likely the only active NeXT user forum still in existence, and asked my question there:
http://www.nextcomputers.org/forums/viewtopic.php?t=3048&sid=4cd22a9f527f6b152ae957ae368ae75f
Halp?!
As you can see from their answers, they thoroughly did not approve of this ‘clever’ installation method. And obviously I was overthinking this whole thing. Install OPENSTEP in a Virtual Machine, and have it serve the netboot environment to the cube. Duh.
It ain’t over till the FAT lady sings
Getting OPENSTEP running in a VM is a pretty trivial process. The whole driver issue is somewhat maddening (dealing with drivers manually always is), but other than that it was clear sailing. The added bonus of using a VM was that I could snapshot the harddrive and keep notes of what was working and what wasn’t.
Remember that little shell script, and the ditto command it ran? Remember that -arch option? Yea well it trims all FAT binaries to only support the currently running architecture. That virtual machine… it runs i386, and the cube… m68k. I can’t just boot the cube off of this install via netboot, cause all m68k support has been stripped/lipo’ed.
I came up with this idea.. I could write a script which went through their install BOM file, find all the FAT binaries, figure out if they were lipo’ed, and if so, reinstall it from the install cd. It took me a couple tries, but I was able to run such a script. It worked, sort of. But afterwards all sorts of things didn’t quite work right (I’d get bizarre errors), which led me to believe that clearly this isn’t a great idea.
What I ended up having to do was setup a secondary harddrive in the VM, and use the tool they have that can create an install disk from the original. I could then edit the installer script to remove the -arch option to ditto. I was careful to not edit any files that might be listed in the BOM to avoid checksum mismatches. I could then boot that secondary harddisk as the installer, and install over the primary disk.
That finally gave me an install where all binaries were FAT with support for i386 and m68k.
Oh right… the point was to boot the cube
NeXT made some really nice GUI network management tools to configure their NetInfo stuff. I read their system administration guide to get a feel for how it should all be setup, and configured everything accordingly. I should mention that those ‘really nice GUI network management tools’ are ‘incredibly thin window dressings’ over the configuration files. In the sense that they do next to no validation of input, and let you put your machine in a state where it can’t boot anymore. Thanks! Needed salt in the wound at this point.
Eventually… when the VM would boot again, and I was confident in what I had done: power up the cube again, and type in ‘ben’ for the millionth time to have it boot over ethernet. The VM fed it the boot info like a champ. Everything’s going swimmingly… the window server starts up. Spinning beachball in glorious 4 shades of gray. Oh no.. I’ve seen this before. I telnet in and check the logs. BuildDisk in a loop again. *throws chair across the room*
I was pretty much convinced at this point that there was something wrong with the cube, hardware-wise. Now, having used OPENSTEP for more than 2 minutes, I know that BuildDisk is the utility that sets up an initial install. The CD copies itself to a disk, then BuildDisk runs and installs the optional pkg files. Part of its process is figuring out where to install, and it looks for fixed disks. That SCSI bus errors out on every boot, likely because it has no terminator on it. Some googling tells me you probably want to avoid interacting with an un-terminated SCSI bus. OK fine! I’ll buy a terminator for it. If I can find one.
I don’t think Ottawa has any stores that sell antiquated stuff like this. I emailed a few places and got either no responses or “we don’t sell that stuff anymore.” I even emailed Syrotech, my goto place in Winnipeg to see if they could ship me one.
But wait… what’s telling BuildDisk that it should run? Why does it think things aren’t setup? To netboot, you have to feed each machine its own /private mount, which is where /etc/ lives, amongst other things. I was able to confirm that nothing outside of /etc/ should be different for the cube than the host machine. Whatever it is, it would have to be in /etc/. So what I ended up doing was copying over the host’s /etc/ into the netboot client’s /etc/, then having to manually switch stuff out to be appropriate for the cube again. It’s worth a shot, right?
Well… that did it. So there’s something in their new-netboot-client template that marks it “not setup yet”, that I was able to work around by just copying the entire /etc. I still want to figure out what that is, and it shouldn’t be too tough, there’s only ~100 or so files in there. I could script something to diff each one and show me all differences. It’s bound to pop up.
The important thing is: It works! I can start it up, and login, and use the thing!
It works… now what?
I now have a working NeXTCube. It boots off the network, it stores its swapfile on the network, and it’s awesome. It’s fantastically slow, which is probably partially because everything is network based (even though 10Mbps is probably about as fast as the hard disks back in the day?), but most likely because it has a 25Mhz processor. My iPhone probably has 100x the processing performance of this thing.
OPENSTEP is actually really, really cool. Of course, dev tool stuff is neat, but I’m actually starting to finally appreciate some of the stuff I’ve heard that I used think was ridiculous. Like tearing off a menu that you use often and keeping it nearby. It comes in super handy.
I’ve been poking around, and trying to get a better feel for what has changed between then and now. One thing I didn’t realize was the fact that you literally had to write postscript to do drawing. The code in an NSView’s -drawRect: from that time really doesn’t resemble today at all. I always assumed that Quartz and DPS had similar front-end code, and that it was mainly a backend difference.
A big part of this for me was just the challenge. At any point, I could have ordered a SCSI disk from BlackHole with OPENSTEP pre-installed and been done with it. But what fun is that? I learned a ton in the process, and despite the loud cursing that could be heard coming out of my office, this type of stuff is actually really fun for me. Fun in a “I never want to go through that again” kind of way, I mean.
I have a project or two that will make serious use of the cube, one of which is actually mostly done already and I’ll probably blog about it in the not-too-distant future.