Operating-system comparisons

For detailed discussion of the technical features of different operating systems, see the OSData website.

VMS is the proprietary operating system originally developed for the VAX minicomputer from Digital Equipment Corporation. It was first released in 1978, was an important production operating system in the 1980s and early 1990s, and continued to be maintained when DEC was acquired by Compaq and Compaq was acquired by Hewlett-Packard. It is still sold and supported in early 2003, though little new development goes on in it today[10]. VMS is surveyed here to show the contrast between Unix and other CLI-oriented operating systems from the minicomputer era.

VMS makes process-spawning very expensive. The VMS file system has an elaborate notion of record types (though not attributes). These traits have all the consequences we outlined earlier on, especially (in VMS's case) the tendency for programs to be huge, clunky monoliths.

VMS features long, readable COBOL-like system commands and command options and excellent on-line help (not for APIs, but for the executable programs and command-line syntax). In fact, the VMS CLI and its help system are the organizing metaphor of VMS. Though X windows has been retrofitted onto the system, the CLI remains the most important stylistic influence on program design. This has major implications for:

VMS has a respectable system of internal boundaries, It was designed for true multi-user operation and fully employs the hardware MMU to firewall processes from each other. The system command interpreter is privileged, but the encapsulation of critical functions is otherwise pretty good. Security cracks against VMS have been rare.

VMS tools were initially expensive, and its interfaces are complex. There are enormous volumes of VMS programmer documentation that are available only in paper form, so looking up anything is a high-overhead operation. This tended to discourage exploratory programming and learning a large toolkit. VMS has only developed casual programming and a hobbyist culture since being nearly abandoned by its vendor, and that culture is not particularly strong.

Like Unix, VMS predated the client/server distinction. It was successful in its day as a general-purpose timesharing operating system. The intended audience was primarily technical users and software-intensive businesses, implying a moderate tolerance for complexity.

The Macintosh operating system was designed at Apple in the early 1980s, inspired by pioneering work on GUIs done earlier at XEROX's Palo Alto Research Center. It debuted with the Macintosh in 1984. MacOS has gone through two significant design transitions since. The first was the shift from supporting only a single application at a time to being able to cooperatively multitask multiple applications (MultiFinder); the second was the shift from 68000 to PowerPC processors, which both preserved backwards binary compatibility with 68K applications and brought in an advanced shared library management system for PowerPC applications, replacing the original 68K trap instruction-based code-sharing system. A third (proceeding in early 2003) is the effort to merge its design ideas with a Unix-derived infrastructure in Mac OS X. Except where specifically noted, the discussion here applies to pre-OS-X versions.

MacOS has a very strong unifying idea that is very different from Unix's — the Mac Interface Guidelines. These specify in great detail what an application GUI should look like and how it should behave. A related and important idea is that things stay where you put them — documents, directories, and other objects have persistent locations on the desktop that the system doesn't mess with, and the desktop context persists through reboots.

The Macintosh's unifying idea is so strong that most of the other design choices we discussed above are either forced by it or invisible. All programs have GUIs. There is no CLI at all. Scripting facilities are present but much less commonly used than under Unix; many Mac programmers never learn them. MacOS's captive-interface GUI metaphor (organized around a single main event loop) leads to a weak scheduler without pre-emption. This, and the fact that all MultiFinder applications run in a single large address space, therefore it is not practical to use separated processes or even threads rather than polling.

This doesn't mean that MacOS applications are invariably monster monoliths, however. The system's GUI support code, which is partly implemented in a ROM shipped with the hardware and partly implemented in shared libraries, communicates with MacOS programs via an event interface that has been quite stable since its beginnings. Thus, the design of the OS encourages a relatively clean separation between application engine and GUI interface.

MacOS also has strong support for isolating application metadata like menu structures from the engine code. MacOS files have both a ‘data fork’ — a Unix-style bag of bytes that contains a document or program code — and a ‘resource fork’ — a set of user-definable file attributes. Mac applications tend to be designed so that (for example) the images and sound used in them are stored in the resource fork and can be modified separately from the application code.

The MacOS system of internal boundaries is very weak. There is a wired-in assumption that it's single-user, so there are no per-user privilege groups. All MultiFinder applications run in the same address space, so bad code in any application can corrupt anything outside the operating system's low-level kernel. Security cracks against MacOS machines are very easy to write; the OS has been spared an epidemic mainly because very few people are motivated to crack it.

Mac programmers tend to design in the opposite direction from Unix programmers — they work from the interface inwards, rather than from the engine outwards. We'll discuss some of the implications of this choice in Chapter 18 (Futures). Everything in the design of the MacOS conspires to encourage this.

The intended role for the Macintosh was as a client operating system for nontechnical end users, implying a very low tolerance for interface complexity. The Macintosh culture became very, very good at designing simple interfaces.

The incremental cost of becoming a developer, assuming you have a Macintosh already, has never been high. Thus, despite rather complex interfaces, the Mac developed a strong hobbyist culture early on. There is a vigorous tradition of small tools, shareware, and user-supported software.

Classic MacOS has been end-of-lifed. Most of its facilities have been imported into Mac OS X, which mates them to a Unix infrastructure derived from the Berkeley tradition. At the same time, leading-edge Unixes such as Linux are beginning to borrow ideas like file attributes (a generalization of the resource fork) from MacOS.

OS/2 began life as an IBM development project called ADOS (‘Advanced DOS’) project, one of three competitors to become DOS 4. At that time, IBM and Microsoft were formally collaborating to develop a next-generation operating system for the PC. OS/2 1.0 was first released in 1987 for the 286, but was unsuccessful. The 2.0 version for the 386 came out in 1992, but by that time the IBM/Microsoft alliance had already fractured. Microsoft went in a different (and more lucrative) direction with Windows 3.0. OS/2 attracted a loyal minority following, but never attracted a critical mass of developers and users. It remained third in the desktop market, behind the Macintosh, until being subsumed into IBM's Java initiative after 1996. The last released version was 4.0 in 1997. Early versions found their way into embedded systems and still, as of early 2003, run many of the world's ATMs.

Like Unix, OS/2 was built to be multitasking and would not run on a machine without an MMU (early versions simulated an MMU using the 286's memory segmentation). Unlike Unix, OS/2 was never built to be multi-user. Process-spawning was relatively cheap, but IPC was difficult and brittle. Thus there were no programs analogous to Unix service daemons, and OS/2 never did multi-function networking very well.

OS/2 had both a CLI and GUI. Most of the positive legendry around OS/2 was about the Workplace Shell (WPS), the OS/2 desktop. Some of this technology was licensed from the developers of the AmigaOS Workbench, a pioneering GUI desktop that still as of 2003 has a loyal fan base in Europe. This is the one area of the design where OS/2 achieved a level of capability which Unix arguably has not yet matched. The WPS was a clean, powerful object-oriented design with understandable behavior and good extensibility. Years later it would become a model for Linux's GNOME project.

The class-hierarchy design of WPS was one of OS/2's unifying ideas. The other was multithreading. OS/2 programmers used threading heavily as a partial substitute for IPC between peer processes. No tradition of cooperating program toolkits developed.

OS/2 actually had a windowing layer beneath the Workplace Shell called the Presentation Manager; these layers separated policy from mechanism in a way analogous to X server vs. X toolkit layering. The separation was never as clean, and became less so with time; in 3.0 they were merged.

OS/2 had the internal boundaries one would expect in a single-user OS. Running processes were protected from each other, and kernel space was protected from user space, but there were no per-user privilege groups, This meant the filesystem had no protection against malicious code. Another consequence was that there was no analog of a home directory; application data tended to be scattered all over the system.

A further consequence of the lack of multi-user capability was that there could be no privilege distinction in userspace. Thus, developers tended to only trust kernel code. Many system tasks which in Unix would be handled by user-space daemons were jammed into the kernel or the WPS. Both bloated as a result.

OS/2 had a text vs. binary mode, but no other file record structure. It supported file attributes, which were used for desktop persistence after the manner of the Macintosh. System databases were mostly in binary formats.

The preferred UI style was through the WPS. User interfaces tended to be ergonomically better than Windows, though not up to Macintosh standards (OS/2's most active period was relatively early in MacOS Classic's history). Like Unix and Windows, OS/2's user interface was themed around multiple, independent per-task groups of windows, rather than capturing the desktop for the running application.

The intended audience for OS/2 was business and non-technical end users, implying a low tolerance for interface complexity. It was used both as a client operating system and as a file and print server.

In the early 1990s, developers in the OS/2 community began to migrate to a Unix-inspired environment called EMX that was designed to emulate POSIX interfaces. Ports of Unix software started routinely showing up under OS/2 in the latter half of the 1990s.

Anyone could download EMX, which included the GNU Compiler Collection and other open-source development tools. IBM intermittently gave away copies of the system documentation in the OS/2 developer's toolkit, which was posted on many BBSs and FTP sites. Because of this, the “Hobbes” FTP archive of user-developed OS/2 software had already grown to over a gigabyte in size by 1995. A very vigorous tradition of small tools, exploratory programming, and shareware developed and retained a loyal following for some years after OS/2 itself was clearly headed for the dustbin of history.

After the release of Windows 1995 the OS/2 community, feeling beleaguered by Microsoft and encouraged by IBM, became increasingly interested in Java. After the Netscape source code release in early 1998 the direction of migration changed (rather suddenly), towards Linux.

OS/2 is interesting as a case study in how far a multi-tasking but single-user operating-system design can be pushed. Most of the observations in this case study would apply well to other operating systems of the same general type — notably AmigaOS[11] and GEM[12]. A wealth of OS/2 material is still available on the Web in 2003, including some good histories [13].

Windows NT (New Technology) is Microsoft's operating system for high-end personal and server use; it is shipped in several variants which can all be considered the same for our purposes. All of Microsoft's consumer operating systems since the demise of Windows ME in 2000 have been NT-based. It is genetically descended from VMS, with which it shares some important characteristics.

NT has grown by accretion, and lacks a unifying metaphor corresponding to Unix's “everything is a file” or the MacOS desktop [14]. Because core technologies are not anchored in a small set of persistent central metaphors, they get obsoleted every few years. Each of the technology generations — DOS (1981), Windows 3.1 (1990), Windows 95 (1995) Windows NT 4 (1996), Windows 2000 (2000), Windows XP (2002) and .NET (in progress as of 2003) — has required that developers relearn fundamental things in a different way, with the old way declared obsolete and no longer well supported.

There are other consequences as well:

  • The GUI facilities coexist uneasily with the weak, remnant command-line interface inherited from DOS and VMS.

  • Socket programming has no unifying data object analogous to the Unix everything-is-a-file-handle, so multiprogramming and network applications that are simple in Unix require several more fundamental concepts in NT.

NT has file attributes in some of its file system types. They are used in a restricted way, to implement access-control lists on some filesystems, and don't affect development style very much. It also has a record-type distinction, between text and binary files, that produces occasional annoyances.

Process-spawning is expensive, scripting facilities are weak, and the OS makes extensive use of binary file formats. In addition to the expected consequences we outlined earlier:

  • Most programs cannot be scripted at all. Programs rely on complex, fragile remote procedure call RPC methods to communicate with each other, a rich source of bugs.

  • There are no generic tools at all. Documents and databases can't be read or edited without special-purpose programs.

  • Over time, the CLI is more and more neglected because the environment there is so sparse, so the problems associated with a weak CLI get worse.

System and user configuration data are centralized in a small set of registries rather than being scattered through numerous dotfiles and system data files as in Unix.

  • This has one advantage — most configuration data is in a common, simple format (one sufficiently general that some Unix programs have adopted it).

  • On the other hand, the registry implementation lacks event listeners, so system programs can't know when the registry has been modified. This is the major reason that Windows reconfiguration so frequently requires a reboot.

  • The registry makes the system completely non-orthogonal. Single-point failures in applications can corrupt the registry, frequently making the entire operating system unusable and requiring a reinstall.

  • The registry creep phenomenon: as the registry grows, rising access costs slow down all programs.

NT systems are notoriously vulnerable to worms, viruses, defacements, and cracks of all kinds. There are many reasons for this; some reasons are more fundamental than others, and the most fundamental is that NT's internal boundaries are extremely porous.

Recent versions have retrofitted in access control lists that can be used to implement per-user privilege groups — but a great deal of legacy code ignores them, and the operating system permits this in order not to break backward compatibility. Furthermore, the registry is not split up by privilege group, so users can read or modify each others' configuration information (possibly including passwords and credentials for other systems) at will. There are no security controls on message traffic between GUI clients, either.

While NT will use an MMU, NT versions after 3.5 have the system GUI wired into the same address space as the privileged kernel for performance reasons. Recent versions even wire the web server into kernel space in an unsuccessful attempt to match the speed of Unix-based web-servers.

These holes in the boundaries have the synergistic effect of making actual security on NT systems effectively impossible. If an intruder can get code run as any user at all (e.g., through the Outlook email-macro feature), that code can forge messages through the window system to any other running application. And any buffer overrun or crack in the GUI or web-server can be exploited to take control of the entire system.

The intended audience for the NT operating systems is primarily nontechnical end-users, implying a very low tolerance for interface complexity. It is used in both client and server roles.

Early in its history Microsoft relied on third-party development to supply applications. They originally published full documentation for the Windows APIs, and kept the price of development tools low. But over time, and as competitors collapsed, Microsoft's strategy shifted to favor in-house development, they began hiding APIs from the outside world, and development tools grew more expensive. As early as Windows 95, Microsoft was requiring non-disclosure agreements as a condition for purchasing professional-quality development tools.

The hobbyist and casual-developer culture that had grown up around DOS and earlier Windows versions was large enough to be self-sustaining even in the face of increasing efforts by Microsoft to lock them out (including such measures as certification programs designed to de-legitimatize amateurs). Shareware never went away, and Microsoft's policy began to reverse somewhat after 2000 under market pressure from open-source operating systems and Java. However, Windows interfaces for professional programming continued to grow more complex over time, presenting an increasing barrier to serious coding.

The result of this history is a sharp dichotomy between the design styles practiced by amateur and professional NT developers — the two groups barely communicate. While the hobbyist culture of small tools and shareware is very much alive, professional NT projects tend to produce monster monoliths even bulkier than those characteristic of ‘elitist’ operating systems like VMS.

Be, Inc. was founded in 1989 as a hardware vendor, building pioneering multiprocessing machines around the PowerPC chip. BeOS was its attempt to add value to the hardware by inventing a new, network-ready operating system model incorporating the lessons of both Unix and the MacOS family, without being either. The result was a tasteful, clean, and exciting design with excellent performance in its chosen role as a multimedia platform.

BeOS's unifying ideas were ‘pervasive threading’, multimedia flows, and the file system as database. BeOS was designed to minimize latency in the kernel, making it well-suited for processing large volumes of data such as audio and video streams in real time. BeOS ‘threads’ were actually lightweight processes in Unix terminology, since they supported thread-local storage and therefore did not necessarily share all address spaces. IPC via shared memory was fast and efficient.

BeOS followed the Unix model in having no file structure above the byte level. Like the MacOS, it supported and used file attributes. In fact, the BeOS filesystem was actually a database that could be indexed by any attribute.

One of the things BeOS took from Unix was intelligent design of internal boundaries. It made full use of an MMU, and sealed running processes off from each other effectively. While it presented as a single-user operating system (no login), it supported Unix-like privilege groups in the filesystem and elsewhere in the OS internals. These were used to protect system-critical files from being touched by untrusted code; in Unix terms, the user was logged in as an anonymous guest at boot time, with the only other ‘user’ being root. Full multi-user operation would have been a small change to the upper levels of the sytem; there was in fact a BeLogin utility.

BeOS tended to use binary file formats and the native database built into the filesystem, rather than Unix-like textual formats.

The preferred UI style of BeOS was GUI, and it leaned heavily on MacOS experience in interface design. CLI and scripting were, however, also fully supported. The command-line shell of BeOS was a port of bash(1), the dominant open-source Unix shell, running through a POSIX compatibility library. Porting of Unix CLI software was, by design, trivially easy. Infrastructure to support the full panoply of scripting, filters and service daemons that goes with the Unix model was in place.

Beos's intended role was as a client operating system specialized for quasi-real-time multimedia processing. Its intended audience included technical and business end-users, implying a moderate tolerance for interface complexity.

Entry barriers to BeOS development were low; though the operating system was proprietary, development tools were inexpensive and full documentation was readily available. The BeOS effort began as part of one of the efforts to unseat Intel's hardware with RISC technology, and was continued as a software-only effort after the Internet explosion. Its strategists were paying attention during Linux's formative period in the early 1990s, and were fully aware of the value of a large casual-developer base. In fact they succeeded in attracting an intensely loyal following; as of 2003 there are no fewer than five separate projects attempting to resurrect BeOS in open source.

Unfortunately, the business strategy surrounding BeOS was not as astute as the technical design. The BeOS software was originally bundled with dedicated hardware, and marketed with only vague hints about intended applications. Later (1998) it was ported to generic PCs and more closely focused on multimedia applications, but never attracted a critical mass of applications or users. BeOS finally succumbed in 2001 to a combination of anti-competitive maneuvering by Microsoft (lawsuit in progress as of 2003) and cost pressure from variants of Linux that had been adapted for multimedia handling.

Linux is the leader of the pack of new-school open-source Unixes that have emerged since 1990 (also including FreeBSD, NetBSD, OpenBSD, Darwin, and Cygwin), and is representative of the design direction being taken by the group as a whole. The trends in it can be taken as representative for this entire group.

Linux does not include any code from the original Unix source tree, but it was designed from Unix standards to behave like a Unix. In the rest of this book, we emphasize the continuity between Unix and Linux. That continuity is extremely strong, both in terms of technology and key developers — but here we emphasize some directions Linux is taking that mark a departure from ‘classical’ Unix tradition.

Many developers and activists in the Linux community have ambitions to win a substantial share of end-user desktops. This makes Linux's intended audience quite a bit broader than was ever the case for the old-school Unixes, which have primarily aimed at the server and technical-workstation markets. This has implications for the way Linux hackers design software.

The most obvious change is a shift in preferred interface styles. Unix was originally designed for use on teletypes and slow printing terminals. Through much of its lifetime it was strongly associated with character-cell video-display terminals lacking either graphics or color capabilities. Most Unix programmers stayed firmly wedded to the command line long after large end-user applications had migrated to X windows-based GUIs, and the design of both Unix operating systems and their applications have continued to reflect this fact.

Linux users and developers, on the other hand, have been adapting themselves to address the nontechnical user's fear of CLIs. They have moved to building GUIs and GUI tools much more intensively than was the case in old-school Unix, or even in contemporary proprietary Unixes. To a lesser but significant extent, this is true of the other open-source Unixes as well.

The desire to reach end-users has also made Linux developers much more concerned with smoothness of installation and software distribution issues than is typically the case under proprietary Unix systems. One consequence is that Linux features binary-package systems far more sophisticated than any analogues in proprietary Unixes, with interfaces designed (as of 2003, with only mixed success) to be palatable to nontechnical end users.

The Linux community wants, more than the old-school Unixes ever did, to turn their software into a sort of universal pipefitting for connecting together other environments. Thus, Linux features support for reading and (often) writing the filesystem formats and networking methods native to other operating systems. It also supports multiple-booting with them on the same hardware, and simulating them in software inside Linux itself. The long-term goal is subsumption; Linux emulates so it can absorb.[15]

The goal of subsuming the competition, combined with the drive to reach the end-user, has motivated Linux developers to adopt design ideas from non-Unix operating systems to a degree that makes traditional Unixes look rather insular. Linux applications using Windows .INI format files for configuration is a minor example we'll cover in Chapter 10 (Configuration); various attempts to adapt CORBA for Linux desktop projects are another. Linux 2.5's incorporation of extended file attributes, which among other things can be used to emulate the semantics of the Macintosh resource fork, is a recent major example at time of writing.

The remaining proprietary Unixes are designed to be big products for big IT budgets. Their economic niche encourages designs optimized for maximum power on high-end, leading-edge hardware. Because Linux has part of its roots among PC hobbyists, it emphasizes doing more with less. Where proprietary Unixes are tuned for multiprocessor and server-cluster operation at the expense of performance on low-end hardware, core Linux developers have explicitly chosen not to accept more complexity and overhead on low-end machines for marginal performance gains on high-end hardware.

Indeed, a substantial fraction of the Linux user community is understood to be wringing usefulness out of hardware as technically obsolete today as Ken Thompson's PDP-7 was in 1969. As a consequence, Linux applications are under pressure to stay lean and mean that their counterparts under proprietary Unix do not experience.

These trends have implications for the future of Unix as a whole, a topic we'll return to in Chapter 18 (Futures).



[10] More information is available at the OpenVMS.org site.

[13] See, for example, the OS Voice and OS/2 BBS.COM sites.

[14] Perhaps. It has been argued that the unifying metaphor of all Microsoft operating systems is “the customer must be locked in”.

[15] The results of Linux's emulate-and-subsume strategy differ noticeably from the embrace-and-extend practiced by some of its competitors — for starters, Linux does not break compatibility with what it is emulating in order to lock customers into the “extended” version.