Who could imagine unix would last so long ?
I’m a big fan of vintage computers, and among them there is one which is considered by everyone to be a classic : the venerable super mini computer VAX 11/780, designed by Digital Equipment Corporation, and released in 1978.
The name VAX comes from the acronym Virtual Address eXtension : it’s a 32 bits computer, a needed evolution from their line of 16 bits mini computers, the PDP-11s, on which the Unix operating systems was invented circa 1970. It’s central processing unit (CPU) is clocked at 5 Mhz (800 times slower than today PCs).
On the VAX, UNIX could become a mature operating system notably by the release named BSD 4.3, for Berkeley Software Distribution version 4.3. It was a bit slow, but most reliable than 4.1 and 4.2. It was enhanced later by the version 4.4 which was slightly faster. BSD4.3 was simple enough to deploy and maintain.
With the latest release of a VAX 11/780 emulation software which now groks about networking, I decided to run my own VAX virtual machine under BSD4.3.
The fact that the emulated VAX supports networking makes things much easier because I can transfert files easily from the Internets to my PC (fast) and then to the VAX at a decent speed.
I followed the usual steps described in the documentation, eg. boot on a miniroot, copy it on the disk, boot on the disk, install the software from the tape, etc.
When the kernel boots for the first time it writes :
WARNING: clock lost 121 days -- CHECK AND RESET THE DATE!
I thought, Ok, system date is wrong, I just need to set the date, how do I do that gain ? I remember, that didn’t change since 1985, I think, it must be the datecommand :
$ date -s usage: date [-n] [-u] [yymmddhhmm[.ss]
Crap. I mean crap not because I was wrong about the -s option, but because of the time format. Yes, the year is a 2 digits number, and if I enter 17 the system will think it is in 1917. Crap. I took a look at the source of date, and indeed the program adds the constant 1900 to the 2 digits : year += 1900; (line 193 of date.c). Crap crap crap and crap.
I was thinking, what would be the fastest way of setting the system to the current date ? Write a small C program with an hardcoded date and set it through the according system call ? That’s a pain in the ass, so I decided to do what I though was straightforward : change the value of the variable _time in the kernel memory. The Unix time is a 32 bits integer value which counts the seconds since January 1 1970.
I searched the internet for “unix time converter” and quickly found the site http://www.unixtimestamp.com/ which looked appropriate.
Current time is 1493139799 so I just have to enter that value in the memory address _time. 1493139799 is not in hexadecimal, and I cannot remember how to enter a number in decimal with the adb debugger. Yes, I planned to use adb, even if it’s prehistoric, it has some neat features to inspect and modify a running kernel, so I used to know it quite well.
1493139799 in decimal is 0x58FF8157 in hexadecimal (base 16) as google says :
I’m all set I though, so LET’S GO!
`$ adb -w /vmunix /dev/kmem time/W0x58FF8157 _time: b72c490 = 56df8157
WTF ? I ask to write the value 0x58FF8157 and the value actually stored is 56df5e0e ? Date is now Tue Mar 8 15:21:00 PST 2016, about one year back.
I won’t lie, it took me some time to find this one. I started by checking the 16 left and right parts of the 32 bits variable _time. The lowest digits were correctly changing every seconds and I could also change the upper 2 bytes :
`_time: 81c0 _time+2: b72c /w5600 _time+2: b72c = 5600 time/X _time: _time: 560081e7
So I could set 0x5600<something>, why not 58 ? Let’s try setting the upper bytes again :
_time+2: 5600 /w58ff _time+2: 5600 = 58ff time/X _time: _time: 58ff8211
Weird, it worked.
Then I saw the difference. What I was entering was a cut & paste of google’s output : 0x58FF8157 and that’s was not working, but when I entered 0x58ff by hand it was working. 0x58FF vs 0x58ff.
Yes. This was the problem : adb doesn’t like uppercase letters in an hexadecimal number, or it likes them but God knows what it does with them, I don’t want to know. If I use lowercase, eg. 0x58ff8157 it works perfectly.
I was lucky (or unlucky?) enough that there was no letters in the lower 16 bits value, that’s why I couldn’t understand why one half could be correctly written and not the other.
$ date Tue Apr 25 14:42:21 PST 2017
Now the serious work can start. Let’s connect to ftp.gnu.org…
ftp> get emacs-18.59.tar.gz 200 PORT command successful. Consider using PASV. 150 Opening BINARY mode data connection for emacs-18.59.tar.gz (2962652 bytes). 226 Transfer complete. local: emacs-18.59.tar.gz remote: emacs-18.59.tar.gz 2962652 bytes received in 71 seconds (40 Kbytes/s) ftp>
I’m happy. Emacs compiles.
But it is too slow to be usable.
- The SIMH emulator. I’m using the latest beta version from github, which includes networking and VAX 11/780 emulation.
- Where BSD4.3 tapes can be found.
- How to install BSD4.3 on the VAX.
- BSD 4.3 sources (in HTML).
- How to setup networking (works like a charm if you use the same device as Windows uses) netstat -rn from cygwin is helpful.
- The VAX 11/780 SIMH documentation.
- Some already compiled GNUdies in SIMH tape format.
- The GNUdies, obviously the old ones http://ftp.gnu.org/old-gnu