There’s More to the 286 XENIX Story

It turns out that there is a rather interesting story behind the 286 XENIX incompatibility with 386 and later processors. Here’s roughly what happened in chronological order.

In 1982, Intel released the iAPX 286 processor, later known as the 80286 or simply 286. This was a highly complex CPU for the time, with an intricate system of software privilege and security enforcement known as protected mode. The 286 used descriptor tables with 48 bits (6 bytes) of information, but in order to keep the design simple, full 64 bits were taken up for each descriptor; the last 16 bits were not used by the CPU and were documented as reserved.

Later in 1982, work was also underway on the 386, Intel’s 32-bit successor to the 286.

In late 1982 or in 1983, Microsoft ported XENIX (a variant of UNIX System III licensed from AT&T) to the Intel 286 processor. Intel and IBM were among companies which licensed the 286 XENIX port from Microsoft. Although Intel had the XENIX source code, the porting was done entirely by Microsoft. Developers at Microsoft decided to store bookkeeping information in the “reserved” 16 bits of a descriptor table entry not used by the 286. This approach reliably worked on 286 processors. Continue reading

Posted in 286, 386, Intel, Microsoft | 33 Comments

PCI Corner Case

Last weekend I had the pleasure of debugging a curious case of older PCI configuration code (circa 2005) failing on newer (post-2010) hardware. The code was well tested on many 1990s and 2000s PCs (and some non-PCs) with PCI/AGP/PCIe and never showed problems. But at least on some newer machines (in my case a Sandy Bridge laptop) it just hung.

I quickly found out that code meant to walk over a PCI capability list got stuck in a loop. But the reason why it got stuck was unexpected. For reasons lost to the mists of time, the code reads the next capability pointer and the capability type (total of 16 bits of information) as two bytes, not one word. That was not the problem though. The problem was that the code always read a full DWORD from the config space and discarded the top bits. On the problematic system, that worked as long as the read was DWORD-aligned, but not otherwise. The code logic may seem unusual but it worked perfectly well on so many older systems, so why not anymore? And who violated the PCI specification, the code or (unlikely) the hardware? Continue reading

Posted in Bugs, Intel, PCI | 1 Comment

IBM XENIX: Two Steps Forward

There are reasons to revisit an old topic. Very old, considering that IBM Xenix 1.0 was released in 1984, well over 30 years ago. To recap, this version of Xenix is unique in that it runs only on 286 processors. It requires a 286 but is incompatible with 386 and later processors due to the use of a reserved word in GDT/LDT descriptors. Good times. And there is a story related to the Xenix 386 incompatibility, but that’s something for another post.

Starting the IBM XENIX installer

Last time the OS/2 Museum attacked IBM Xenix, the incompatibility with any 32-bit x86 processors was a big hurdle. In the meantime, VirtualBox learned to emulate a 286 processor (version 5.1.16 or later). The emulation is far from perfect but it is good enough to run IBM Xenix 1.0 with only slight patching. The required modifications concern incompatibility of IBM Xenix 1.0 with post-PC/AT hardware, namely EGA/VGA graphics and hard disks bigger than 20 or 30 MB. Both issues had been explored 30+ years ago by contemporary Xenix users. Continue reading

Posted in 286, IBM, VirtualBox, Xenix | 7 Comments

Tales From the Xenix Crypt

What does Xenix have to do with the Enigma machine? Perhaps surprisingly, there is a clear connection…

When reconstructing 386 Xenix 2.2.3, the libmdep.a library proved to be a particularly tough nut to crack. That is because it’s one of the three files in a standard Xenix install (/xenix, /etc/getty, /usr/sys/mdep/libmdep.a) which need to be “branded”. Let’s back up a bit and describe the SCO Xenix copy protection.

The Xenix disks did not use any kind of physical copy protection. The media could be backed up and copied without any technical difficulties. The copy protection consisted of a serial number and an activation key which needed to be used in order to “brand” a Xenix installation before it could be used. The branding process wrote a scrambled copy of the serial number into the files, and for files other than the kernel, also decrypted the data which was shipped encrypted on the installation disks.

The installation disks were no good without the serial number and activation key, and if files installed on hard disk were copied, they would contain the serial number and could thus be traced to the source. The mechanism was just complex enough that it was not trivial to defeat, although from a modern perspective the cryptography used was laughably weak.

The Xenix kernel was special in that it was branded but not encrypted, but without a valid serial number severely restricted the number of concurrent processes. It was just good enough to install the OS from floppies but not enough to run a multi-user system.

Now back to libmdep.a. On the restored disks, one sector near the beginning of the library was missing. It turned out that reconstructing the data was not that hard: The missing 512 bytes covered part of the symbol directory and part of the OMF header of the first object file. The OMF header was recreated by copying it from another file and tweaking slightly, and ar had no trouble recreating the symbol directory. So we have a working libmdep.a but  we need an encrypted library which the installation process can decrypt.

Now, Xenix comes with /etc/brand which does what the name suggests. It writes the serial number into files and decrypts files which are shipped encrypted. But when renamed to debrand, the exact same binary turns around and encrypts files (as it happens, the encryption is symmetric). So obviously the debrand utility can be used to encrypt the reconstructed library for placement on the installation media. But just as obviously, debrand needs some kind of key or password, and that is not the serial number or activation key. Rather, it is a separate 3-character code. Which we don’t have. Continue reading

Posted in SCO, Software Hacks, Xenix | 7 Comments

What a Coincidence


  • Mid-1988: SCO 386 Xenix 2.2.3 is released
  • 1996 (probably): Someone dumps the 386 Xenix 2.2.3 disks, but enough sectors are missing that the OS is impossible to install
  • January 3rd, 2013: OS/2 Museum posts about the damaged Xenix dump
  • February 19th, 2017: Michael Casadevall asks about restoring 386 Xenix 2.2.3
  • Late February 2017: Michael and Michal successfully restore 386 Xenix 2.2.3
  • March 3rd, 2017: Someone posts on Reddit about rediscovered 386 Xenix 2.2 disks
  • March 5th, 2017: The same person (almost certainly) uploads the disks on
  • March 6th, 2017: Michael publishes the first of a series of articles about the restoration
  • March 9th: Michal publishes an article which mentions the restoration
  • March 10th: John Elliott points out the fresh disk dump on

Almost 30 years after Xenix 2.2.3 was released, it’s really hard to believe this is a coincidence. But it is, because until March 10th Michael & Michal knew nothing of the dump on, and the person uploading the dump couldn’t have known about the restoration project because it was first publicly mentioned a day after the new disk images were uploaded to

To be clear, the dump is of Xenix 386PS, that is Xenix for PS/2 systems. The Xenix release being restored is 386AT, that is Xenix for PC/AT compatible 386 systems. So the disks aren’t identical, but they are really close. Before embarking on the restoration project, we of course checked what other Xenix releases were available. 386 Xenix 2.2.x was not… until a few days ago. Incredible.

Posted in PC history, Xenix | 1 Comment

Oldest Surviving 386 PC OS?

Four years ago, the Xenix 2.2.3 mystery cropped up (twice). The issue has been revisited and thanks to Michael Casadevall, an enthusiastic reader, came to a happy conclusion:

386 Xenix 2.2.3c booting up

386 Xenix version 2.2.3 was finalized in late June 1988 (the newest files are timestamped June 27, 1988) and is thus one of the oldest surviving 386 PC operating systems.To put it in perspective, it was released at about the same time as IBM DOS 4.0 and several months before OS/2 1.1.

It is not the oldest since 386 Xenix 2.2.2 was released sometime in late 1987 (more or less coinciding with the release of 16-bit OS/2 1.0!), and there were possibly 386 Unixes from Microport and/or ISC available in mid to late 1987, though evidence is lacking.

At any rate, the search is for the oldest 386 PC OS, that is an operating system which runs on 386 PC compatibles, has at least substantial amount of 32-bit code in its core, is a self-contained system (i.e. no DOS extenders), can run 32-bit applications, and ideally uses paging. 386 Xenix checks all those boxes. Continue reading

Posted in 386, Microsoft, SCO, UNIX, Xenix | 21 Comments

More Data on CF to IDE to SCSI

To get a better picture of the performance of the CF to IDE to SCSI solution, I moved the Adaptec 1542C into one of my favorite boards, the Alaris Cougar with a classic Intel 486 DX2 OverDrive CPU.

For a 486, the board has a surprisingly fast IDE controller, an Adaptec 25-VL010 (that’s a VLB IDE controller). With a CF card plugged to the onboard IDE connector, Norton SysInfo 8.0 shows whopping 7 MB/s transfer speed. That is in fact much better than what a typical PCI Pentium board can do (around 3-4 MB/s is common).

AHA-1542C (ISA) and AHA-2842A (VLB)

The performance of the 1542C was somewhat disappointing. That is to say, it was no faster than the ISA-only 386 board, and if anything just a tad slower, with slightly under 2.5 MB/s transfer rate. I tried increasing the AHA-1542C DMA transfer rate from the default 5 MB/s but couldn’t push it much and it made little difference. Continue reading

Posted in 486, CompactFlash, IDE, Storage | 15 Comments

Resetting Disks Is Hard

After digging through BIOS listings and disassembling the Adaptec 1542C BIOS as well as the PC DOS 2000 boot sector, it’s clear why the floppy-less SCSI boot does not work on my test system. It’s because disk reset done by the boot sector (INT 13h/00h) fails when booting off SCSI. But the details are… interesting.

The root of the problem is that the INT 13h/00h service (Reset Disk System) behaves in a rather unexpected and to some extent very surprising manner. For reasons that aren’t obvious, resetting a fixed disk (BIOS drive 80h) also resets the floppy subsystem. And for that reason, the Adaptec 1542C BIOS, which hooks the INT 13h vector, has a relatively complicated disk reset logic (see below).

At a quick glance, MS-DOS 6.22 should behave exactly like PC DOS 2000 in this regard. It executes the same INT 13h/00h call with DL holding the boot drive number. Continue reading

Posted in BIOS, Bugs, SCSI | 22 Comments

Booting Is Hard

So I had this brilliant idea of using SCSI drives with old 286/386/486 boards which have old BIOSes that can’t handle IDE drives bigger than 500-ish megabytes. The SCSI HBA is the first one I happened to grab, an Adaptec 1542C (good because it has a floppy controller onboard); I got the HBA some time ago for free but sans microcode and BIOS chips, and eventually plugged in EPROMs that I burned myself.

To make it more fun, at the other end of the SCSI cable is an Acard IDE-to-SCSI adapter which has a CF-to-IDE adapter attached to it, and plugged into that is a CF card (or a microdrive). Yes, that actually works… up to a point.

CF to IDE to SCSI Frankendrive

Smaller CF cards are a bit problematic because the Adaptec HBA uses a different geometry  than IDE. Remember that SCSI drives have no “physical” geometry and everything is strictly LBA, but the BIOS has to present a logical geometry. For drives smaller than 1 GB, the Adaptec HBA uses 64 heads and 32 sectors per track, which has the nice property that 1 cylinder = 1 MB. But IDE drives essentially never use such logical geometry. For larger drives, the Adaptec HBA uses 255 heads and 63 sectors per track, which happens to match typical IDE large-drive logical geometry. What that means is that larger CF cards should have the same logical geometry when they’re plugged straight into IDE or go via SCSI, and should be accessible and bootable without trouble. Well, I was half right about that. Continue reading

Posted in 386, BIOS, CompactFlash, DOS, SCSI | 16 Comments

Spot the Fakes

Would you believe that besides all the other Made in China fake brand-name items, there are also fake memory modules? Of course you would! At least Kingston and Samsung modules have been seen in the wild; the Kingston ones are depressingly common.

Two out of these four Kingston Value RAM modules are fake (click on the image for higher-res photo). Let’s call them A, B, C, D starting at the top. Can you figure out which ones are the fakes?

Four Kingston-branded DIMMs

The two fakes have been purchased on Amazon within the last few weeks (the genuine ones are from the spare parts pile). It is unclear whether the sellers even realize they’re selling fake goods. Kingston provides some helpful information because they clearly have been fighting with counterfeit products for a while. Continue reading

Posted in DDR RAM, Fakes | 16 Comments