Andrew Tanenbaum has a new book out. For Tanenbaum's many fans, this is a major piece of news, somewhat like hearing that Volume 4 of Knuth's Art of Computer Programming has come out (it hasn't) or that Volume 18 of Inside Macintosh has just appeared. I know that Ray Duncan reviewed Tanenbaum's new book, Modern Operating Systems, in last month's "Programmer's Bookshelf," but I really couldn't resist saying some more about it in this month's column.
Modern Operating Systems is in some ways an update of Tanenbaum's earlier book on his UNIX-compatible operating system, MINIX (Operating Systems: Design and Implementation, 1987), except that the new book doesn't present the source code for an operating system, and is much less about UNIX. Instead, the book presents in-depth case studies of four operating systems: two "traditional" operating systems (MS-DOS and UNIX) and two distributed operating systems (Mach and Tanenbaum's Amoeba).
The coverage of MS-DOS is surprising and welcome. Once again, Tanenbaum has come through with an introductory textbook that deals with the real world. In addition to presenting a fairly accurate picture of the most widely used operating system of all time, it also provides some valuable lessons: "If anyone had realized that within 10 years this tiny system that was picked up almost by accident was going to be controlling 50 million computers, considerably more thought might have gone into it."
Besides the case studies, there are very detailed chapters on processes, memory management, file systems, input/output, and deadlocks. This provides excellent background to read along with the ongoing DDJ series by the Jolitzes, on porting BSD UNIX to the 386.
The entire second half of Modern Operating Systems is on distributed operating systems: the client-server model and remote procedure call (RPC); threads; processes and processor allocation; and distributed file systems. The 30-page section on RPC deserves to be read by anyone even remotely (sorry) interested in the problems of getting two programs to talk to each other. And if you have been wondering about the thinking behind so-called "microkernel" operating systems like Microsoft's NT, this is the place to start. (There's no mention of NT, of course, but it's all applicable.)
The idea behind a microkernel is that most of the services traditionally provided by an operating-system kernel can be moved into user-level processes. As Tanenbaum explains, the microkernel does basically nothing; it simply provides the essence of operating-system-hood, a framework or substrate on which services such as file systems, system API calls, and process management can be built. This means that multiple operating-system interfaces can be plugged in on top of the same microkernel. That is exactly what Microsoft wants to do in NT. I guess we'll find out in a few years if anyone wants it.
This brings up an interesting point about MS-DOS. A frequent complaint about DOS is that it barely merits being called an operating system, since it provides so little. But that's exactly what a microkernel is! Okay, so the services provided by a modern microkernel are better thought-out than the ones DOS provides, but DOS is still essentially a place for folks to plug in their own extensions. You don't like the memory-management system in DOS? (Who does?) Then you can get a memory manager or a DOS extender. You don't like the file system? There are tons of network file systems available. To get a true feel for DOS, you have to look not at what Microsoft has provided in IO.SYS and MSDOS.SYS, but at what third-party vendors have built on top of it (networks, protected-mode DOS extenders, environments such as Windows, TSRs, drivers, you name it). And it's a lot more "micro" than those microkernels, too.
Interestingly, Tanenbaum's own MINIX is modeled much like a distributed operating system. Both the memory manager and the file system reside outside the kernel; they are separate processes that communicate with the rest of the system via messages.
Now, this mention of messages should make a light bulb go off in the head of anyone working with a message-based, event-driven environment such as Microsoft Windows. Much of the material from Tanenbaum on distributed operating systems is readily applicable to Windows and other message-based environments. In one particularly useful section, Tanenbaum demonstrates the equivalence of all interprocess-communications (IPC) primitives, showing, for example, how semaphores and monitors can be built in terms of messages.
In contrast to microkernels, there is the traditional "monolithic" kernel. According to Tanenbaum,
...the only potential advantage of the monolithic kernel is performance. Traping to the kernel and doing everything there may well be faster than sending messages to remote servers. However...other factors tend to dominate, and the small amount of time required to send a message and get a reply (typically about 1 msec) is usually negligible.
This makes sense; if you're really worried about performance, you should be working to minimize the number of operating-system calls you make in the first place.
In his preface, Tanenbaum says he plans to update his MINIX book in the foreseeable future, to produce an up-to-date, hands-on book. I am looking forward to this new MINIX book. Mind you, I have little use for UNIX itself (except that I'm totally dependent on it for e-mail, the editor I use is UNIX-inspired, and all the utilities I depend on are, too). I figure that if you make an operating-system that graduate students will want to use, then only graduate students will want to use it. But, almost everything in these books is applicable to systems programming in general, anywhere.
More important, UNIX is the only operating system that's been subjected to rigorous dissection and explanation of its design and implementation. In addition to Tanenbaum's books, there is Comer's Operating System Design: The Xinu Approach, Bach's The Design of the Unix Operating System, Leffler et al.'s Design and Implementation of the 4.3BSD Unix Operating System and, of course, the Jolitz series running in DDJ (which will, I certainly hope, be turned into a book). There is also the original Lions book, Source Code and Commentary on UNIX Level 6 but this is (ahem) no longer available. (Somewhat off the subject, I am surprised that there is no book like this on the inner workings of X-Windows.)
I know of no such book for MS-DOS. There is only one book on DOS that even attempts an inside look, but it doesn't provide source code for a DOS clone, is written largely (though not entirely) by outsiders, and doesn't attempt to explain how all the pieces tie together. (For one thing, the book has not a single diagram!) My point is simply that, if you're interested in how operating systems work, then you really ought to pick up a few of these textbooks on UNIX internals, even if you have no interest in UNIX itself.
I said a moment ago that UNIX is the only operating system that's been subjected to rigorous explanation of its design and implementation. Actually, that's not quite true: OS/2 also has produced this sort of literature.
Readers may recall that a number of years ago a good book titled Inside OS/2 came out under Gordon Letwin's name. It seems a shame that no such book exists for DOS or Windows, which matter far more than UNIX or OS/2 (though OS/2 2.0 may still surprise us all). Perhaps it's because there's no design (other than what Tanenbaum calls "The Big Mess") to describe in the first place? Perhaps there's even a direct correlation between this ad hoc (ad hack?) approach and success in the marketplace?
In any case, there is a new book on the design of 32-bit OS/2 2.0. One of the authors of The Design of OS/2 is Michael Kogan from IBM, and the other is Harvey Deitel, a writer of operating-systems textbooks. Whatever you think of OS/2 itself, this book really is worth reading. Nothing in here shines like Tanenbaum's book, but I found the discussions of OS/2 kernel architecture, 1.x and 2.x memory management, and compatibility useful. The "Kernel Architecture" section describes a number of OS/2 internal data structures; the memory-management sections have good discussions of arenas.
The book contains an entire chapter called "Compatibility." This in many ways is the most important chapter in the book, just as compatibility is in many ways the most important part of an operating system (and one not discussed by Tanenbaum, by the way). OS/2 2.0, will live or die by its ability to run "old" applications from DOS and Windows. This chapter contains excellent discussions of some of the tricks and hackery needed to run old software on new operating systems.
Actually, one of the things that becomes clear while reading this book is that OS/2 2.0 isn't all that new. While it runs 32-bit applications and has a 32-bit programming interface, much of the system is still 16-bit. OS/2 2.0 device drivers are still 16 bit for example, which is a good thing, not a bad thing, because it means that this time around there will be some printer drivers available!
Consequently, the need to mix 16-bit and 32-bit code is something that seems to be much better thought-out in OS/2 2.0 than in Microsoft's NT. This mixing strikes me as a positive, rather than a negative, about OS/2 2.0. Except: IBM is going around claiming that OS/2 represents a clean slate, instead of a "thing on a thing" like Windows. This is a stupid claim, for two reasons. First, OS/2 is as much a "thing on a thing" as Windows or a DOS ex ender. (The authors call it "a hybrid of 16-bit and 32-bit code internally.") Second, the fact that OS/2 2.0 is such a hybrid may well give it an edge over NT, which is so pure that 32-bit Windows applications won't be able to call 16-bit code. (On the other hand, if you've read Tanenbaum, you know the solution to that problem: If you can't make a function call, use messages instead, and package them up as function calls. In other words, write a 16-bit Windows application to call the 16-bit DLL, and send messages from the 32-bit Windows application to the 16-bit application.)
There is also plenty annoying about this book. It oversells what seem like minor innovations by the IBM development team, such as LDT tiling. It also has the same padded lists of terminology in every chapter that Deitel uses in his other books, and perfectly idiotic exercises. ("6.19: What are infosegs? What kinds of information appear in the global infoseg? What kinds of information appear in the local infosegs?") The authors should look at Tanenbaum's book to see the right way to do end-of-chapter exercises.
Copyright © 1992, Dr. Dobb's JournalInside OS/2 Again