Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.



Published on

  • Be the first to comment

  • Be the first to like this


  1. 1. The Nachos Instructional Operating System Wayne A. Christopher, Steven J. Procter, and Thomas E. Anderson Computer Science Division University of California Berkeley, CA 94720 Abstract In teaching operating systems at an undergraduate level, it is very important to provide a project that is realistic enough to show how real operating systems work, yet simple enough that the students can understand and modify it in signi cant ways. A number of these instructional systems have been created over the last two decades, but recent changes in hardware and software design, along with the increasing power of available computational resources, have changed the basis for many of the tradeo s made by these systems. We have implemented an instructional operating system, called Nachos, and designed a series of assignments to go with it. Our system includes CPU and device simulators, and runs as a regular UNIX process. Nachos illustrates and takes advantage of modern OS technology, such as threads and remote procedure calls, recent hardware advances, such as RISCs and the prevalence of memory hierarchies, and modern software design techniques, such as object- oriented programming and distributed computing. We have used Nachos in the undergraduate operating systems class at Berkeley, with positive results. Nachos is freely available, and we would like to see it widely used for undergraduate instruction.1 IntroductionIn undergraduate computer science education, course projects provide a useful tool for teachingbasic concepts and for showing how those concepts can be used to solve real-world problems. Arealistic project is especially important in undergraduate operating systems courses, where many ofthe concepts are best taught, we believe, by example and experimentation. This paper discusses an operating system, simulation environment, and set of assignments thatwe developed for the undergraduate operating systems course at Berkeley. Over the years, numerous projects have been developed for teaching operating systems amongthe published ones are Tunis Holt 1983] and Minix Tanenbaum 1987b, Aguirre et al. 1991]. Manyof these projects were motivated by the development of UNIX Ritchie & Thompson 1974] in themid 70s. Earlier operating systems, such as MULTICS Daley & Dennis 1968] and OS/360 Mealyet al. 1966] were far too complicated for an undergraduate to understand, much less modify, in a A copy of Nachos can be obtained by anonymous ftp from, le nachos/nachos-2.0.tar". Theauthors e-mail addresses are ffaustus,procter, This work was supported in part by a grant fromthe College of Engineering, University of California at Berkeley. 1
  2. 2. semester. Even UNIX itself is too complicated for this purpose, but UNIX showed that operatingsystems need only a few simple but powerful interfaces, and that the core of an operating system canbe written in only a few dozen pages Lions 1977]. Indeed, the project previously used at Berkeley,the TOY Operating System, was originally developed by Brian Kernighan in 1973. The introduction of minicomputers, and later, workstations, also aided the development of in-structional operating systems. Rather than having to run the operating system on the bare hardware,computing cycles became cheap enough to make it feasible to execute an operating system kernelusing a simulation of real hardware. The operating system can run as a normal UNIX process, andinvoke the simulator when it would otherwise access physical devices or execute user instructions.This vastly simpli es operating systems development, by reducing the compile-execute-debug cycleand by allowing the use of o -the-shelf symbolic debuggers. Because of these advantages, manycommercial operating system development e orts now routinely use simulated machines Bedichek1990]. However, recent advances in operating systems, hardware architecture, and software engineeringhave left many operating systems projects developed over the past two decades out of date. Network-ing and distributed applications are now commonplace. Threads are crucial for the construction ofboth operating systems and higher-level concurrent applications. And the cost-performance trade-o s among memory, CPU speed and secondary storage are now quite di erent from those imposedby core memory, discrete logic, magnetic drums, and card readers. For these reasons, we decided to design and implement a new teaching operating system andsimulation environment. Our system, called Nachos, makes it possible to give assignments thatrequire students to write signi cant portions of each of the major pieces of a modern operating sys-tem: thread management, le systems, multiprogramming, virtual memory, and networking. We usethese assignments to illustrate concepts that we believe are necessary to understand the computersystems of today and of the future: concurrency and synchronization, caching and locality, the trade-o between simplicity and performance, building reliability from unreliable components, dynamic Tasks andscheduling, the power of a level of translation, distributed computing, layering, and virtualization. assignments In building Nachos, we were continually faced with a tradeo between simplicity and realism.For example, a complete UNIX-like le system would be too complicated for students to understandin only a few weeks. Our approach was to build the simplest implementation we could think of foreach sub-system of Nachos this provides students a working example, albeit overly simplistic, ofthe operation of each component of an operating system. The assignments ask the students to addfunctionality to this bare-bones system and to improve its performance on micro-benchmarks thatwe provide. As a result of our emphasis on simplicity, the Nachos operating system is about 2500lines of code, about half of which are devoted to interface descriptions and comments.1 It is thuspractical for students to read, understand, and modify Nachos during a single semester course. We have used Nachos for one term as the project for the undergraduate operating systemscourse at Berkeley we then revised both the code and the assignments based on our experienceswith using it. Nachos currently runs only on DEC MIPS workstations, but we believe that it wouldbe straightforward to port to other platforms. The rest of this paper describes Nachos in more detail. Section 2 provides an overview of NachosSection 3 describes the Nachos assignments. Sections 4 and 5 summarize our experiences. 1 The hardware simulator takes up another 2500 lines, but students need not understand the details of its operation. 2
  3. 3. 2 Nachos OverviewLike many of its predecessor instructional operating systems, the Nachos kernel and hardware simu-lator run together in the same UNIX process.2 Nachos has several signi cant di erences with earliersystems: Because we simulate a standard, well-documented, instruction set (MIPS R2/3000 integer instructions Kane 1987]), we can run normal C programs as user programs on our operating system. In the past, operating systems projects typically simulated their own ad hoc instruction set, requiring user programs to be written in assembly language. Because the R2/3000 is a RISC, it can be simulated with only about 10 pages of code. We accurately simulate the behavior of a network of workstations, each running Nachos. We connect Nachos machines", each running as a UNIX process, together via sockets. A thread on one machine" can then send a message to a thread running on a di erent machine" of course, both are simulated on the same physical hardware. Our simulation is deterministic. Debugging non-repeatable execution sequences is a fact of life for professional operating systems engineers, but it did not seem advisable for us to make that experience our students rst introduction to operating systems. Instead of using UNIX signals to simulate asynchronous devices such as the disk and the timer, Nachos maintains a simulated time that is incremented whenever a user program executes an instruction and whenever a call is made to certain low-level operating system routines. Interrupt handlers are then invoked when the simulated time reaches the appropriate point.3 Our simulation is also randomizable to add unpredictable, but repeatable, behavior. For instance, the network simulation randomly chooses which packets to drop provided the initial seed to the random number generator is the same, however, the behavior of the system is repeatable. Nachos is implemented in a subset of C++. Object-oriented programming is becoming more popular, and we found that it was a natural idiom for stressing the importance of modularity and clean interfaces in building operating systems. To simplify matters, we omitted certain aspects of the C++ language: derived classes, operator and function overloading, and C++ streams. We also kept inlines to a minimum. Although our students did not know C++ before taking our course, we found that they learned the language very easily. The Nachos assignments take a quantitative approach to operating system design. Frequently, the choice of how to implement some piece of operating system functionality comes down to a tradeo between simplicity and performance. We believe that teaching students how to make informed decisions about tradeo s is one of the key roles of an undergraduate operating systems course. The Nachos hardware simulation re ects current hardware performance characteristics 2 Minix takes the di erent approach of running directly on personal computers. While this approach is morerealistic, it makes debugging more di cult. 3 The one aspect of the simulation we did not make reproducible was the precise timing of network communications,but since this came at the end of the semester, it did not seem to cause problems. 3
  4. 4. we exploit this by having students measure the performance of their implementations on some simple workloads that we provide. 3 The Assignments Nachos contains ve major components, each the focus of one assignment given during the semester: thread management and synchronization, the le system, user-level multiprogramming support, the virtual memory system, and network support. Each assignment is designed to build upon previous ones for instance, every part of Nachos uses thread primitives for managing concurrency. This re ects part of the charm of developing operating systems: you get to use what you build." In this section, we discuss each of the ve assignments, including the hardware simulation fa- cilities and the operating system structures we provide, along with what we ask the students to implement. Students worked in pairs, and we conducted 15 minute graded design reviews after every assignment. We found that the design reviews were very helpful at encouraging students to design before implementing. 3.1 Thread Management The rst assignment introduces the concepts of threads and concurrency. We provide students with a basic working thread system and an implementation of semaphores the assignment is to implement Mesa-style locks and condition variables Lampson & Redell 1980] using semaphores, and then to implement solutions to a number of concurrency problems using these synchronization primitives. For instance, we ask students to program a simple producer-consumer interaction through a bounded bu er, using condition variables to denote the bu er empty" and bu er full" states. In much the same way as pointers for beginning programmers, understanding concurrency re- quires a conceptual leap on the part of students. Contrary to Dijkstra Dijkstra 1989], we believe that the best way to teach concurrency is with a hands-on" approach. Nachos helps in two ways. First, thread management in Nachos is explicit: students can trace, literally statement by statement, what happens during a context switch from one thread to another, both from the perspective of an outside observer and from that of the threads involved. We believe this experience is crucial to de-mystifying concurrency. Precisely because C and C++ allow nothing to be swept under the covers, concurrency may be easier to understand (although harder to use) in these programming languages than in those explicitly designed for concurrency, such as Ada Mundie & Fisher 1986], Modula-3 Nelson 1991], and Concurrent Euclid Holt 1983]. Second, a working thread system, as in Nachos, allows students to practice writing concurrent programs and to test out those programs. Even experienced programmers nd it di cult to think concurrently a widely used OS textbook had an error in one of its concurrent algorithms that went undetected for several years. When we rst used Nachos, we omitted many of the practice problems we now include, thinking that students would see enough concurrency in the rest of the project. In retrospect, the result was that many students were still making concurrency errors even in the nal phase of the project. Our thread system is based on FastThreads Anderson et al. 1989]. Our primary goal was simplicity, to reduce the e ort required for students to trace the behavior of the thread system.Check this Threadsystem 4
  5. 5. Our implementation is a total of about 10 pages of C++ and a page of MIPS assembly code. Forsimplicity, thread scheduling is normally non-preemptive, but to emphasize the importance of critical Imp Infosections, we have a command-line option that causes threads to be time-sliced at random", butrepeatable, points in the program. Concurrent programs are correct only if they work when acontext switch can happen at any time".3.2 File SystemsReal le systems can be very complex artifacts. The UNIX le system, for example, has at leastthree levels of indirection | the per-process le descriptor table, the system-wide open le table,and the in-core inode table | before one even gets to disk blocks. As a result, in order to build a le system that is simple enough for students to read and understand in a couple of weeks, we wereforced to make some hard choices as to where to sacri ce realism. We provide a basic working le system that is as stripped of as much functionality as possible.While the le system has an interface similar to that of UNIX Ritchie & Thompson 1974] (castin terms of C++ objects), it also has many signi cant limitations with respect to commercial lesystems: there is no synchronization (only one thread can access the le system at a time), leshave a very small maximum size, les have a xed size once created, there is no caching or bu eringof le data, the le name space is completely at (there is no hierarchical directory structure), andthere is no attempt at providing robustness across machine and disk crashes. As a result, our basic le system takes only about 15 pages of code. The assignment is rst, to correct some of these limitations, and second, to improve the perfor-mance of the resulting le system. We list a few possible optimizations, such as caching and diskscheduling, but it is up to the students to decide which are the most cost-e ective for our benchmark(the sequential write and then read of a large le). At the hardware level, we provide a disk simulator, which accepts read sector" and writesector" requests and signals the completion of an operation via an interrupt. The disk data is storedin a UNIX le read and write sector operations are performed using normal UNIX le reads andwrites. After the UNIX le is updated, we calculate how long the simulated disk operation shouldhave taken (from the track and sector of the request), and set an interrupt to occur that far in thefuture. Read and write sector operations (emulating hardware) return immediately higher levelsoftware is responsible for waiting until the interrupt occurs. We made several mistakes along the way of developing the Nachos le system. In our rstattempt, the le system was much more realistic than the current one, but it also took more thanfour times as much code. We were forced to re-write it to cut it down to something that studentscould quickly read and understand. When we handed out this simpler le system, we did not provideenough code for it to be completely working, leaving out le read and write operations to be writtenby the students. Although these are fairly straightforward to implement, the fact that our code didnot work meant that students had di culty understanding how each of the pieces of the le system t together. We also initially gave students the option of which limitations to x from our experience, wefound that students learned the most from xing the rst four listed above. The result is that,even though virtually all modern le systems include some form of write-ahead logging or log-structure Rosenblum & Ousterhout 1992], the assignment now completely ignores the issue of crash 5
  6. 6. recovery. This is simply a tradeo in the limited time available, we focus on how basic le systemswork, how the le abstraction allows disk data layout to be radically changed without changing the le system interface, and and how caching can be used to improve I/O performance.3.3 MultiprogrammingIn the third assignment, we provide the code to create a user address space, load a Nachos lecontaining an executable image into user memory, and then to run the program. Our initial code isrestricted to running only a single user program at a time. Students expand on this base to supportmultiprogramming. Students implement a variety of system calls (such as UNIX fork and exec), aswell as a user-level shell. We also ask them to optimize the multiprogramming performance of theirsystem on a mixed workload of I/O- and CPU-bound jobs. While we supply relatively little Nachos code as part of this assignment, the hardware simulationdoes require a fair amount of code. We simulate the entire MIPS R2/3000 integer instruction set anda simple single-level page table translation scheme. (For this assignment, a programs entire virtualaddress space must be mapped into physical memory true virtual memory is left for assignmentfour.) In addition, we provided students an abstraction that hid most of the details of the MIPSobject code format. This assignment requires few conceptual leaps, but it does tie together the work of the previoustwo assignments, resulting in a usable, albeit limited, operating system. Because our simulator canrun C programs, our students found it easy to write the shell and other utility programs (such asUNIX cat") to exercise their system. (One overly ambitious student attempted to port emacs.) Theassignment illustrates that there is little di erence between writing user code and writing operatingsystem kernel code, except that user code runs in its own address space, isolating the kernel fromuser errors. One important topic we chose to leave out (again, as a tradeo against time constraints) isthe trend toward a small-kernel operating system structure, where pieces of the operating systemare split o into user-level servers Wulf et al. 1974]. Because of its modular design, it wouldbe straightforward to move Nachos towards a small-kernel structure, except that (i) we have nosymbolic debugging support for user programs and (ii) we would need a stub compiler to make iteasy to make procedure calls across address spaces.3.4 Virtual MemoryAssignment four asks students to replace their simple memory management code from the previousassignment with a true virtual memory system, that is, one that presents to each user program theabstraction of an (almost) unlimited virtual memory size by using main memory as a cache for thedisk. We provide no new hardware or operating system components for this assignment. The assignment has three parts. First, students implement the mechanism for page fault handling| their code must catch the page fault, nd the needed page on disk, nd a page frame in memoryto hold the needed page (writing the old contents of the page frame to disk if it is dirty), readthe new page from disk into memory, adjust the page table entry, and then resume the executionof the program. This mechanism can take advantage of what the students have built in previous 6
  7. 7. assignments: the backing store for an address space can be simply represented as a Nachos le, andsynchronization is needed when multiple page faults occur concurrently. The second part of the assignment is to devise a policy for managing the memory as a cache| for deciding which page to toss out when a new page frame is needed, in what circumstances(if any) to do read-ahead, whether or not to write unused, dirty pages back to disk in advance tospeed later page fault handling, and how many pages to bring in before initially starting to run aprogram Levy & Lipman 1982, Le er et al. 1989]. These policy questions can have a large impact on overall system performance, in part becauseof the large and increasing gap between CPU speed and disk latency | this gap has widened bytwo orders of magnitude in only the last decade. Unfortunately, the simplest policies often haveunacceptable performance. To encourage students to implement realistic policies, the third part ofthe assignment is to measure the performance of the paging system on a benchmark we provide| a matrix multiply program where the matrices do not t in memory. This workload is clearlynot representative of real-life paging behavior, but it is simple enough that students can understandthe impact of policy changes on the application. Further, the application illustrates some of theproblems with caching | small changes in the implementation of matrix multiply can have a largeimpact on performance Lam et al. 1991].3.5 NetworkingAlthough distributed systems have become increasingly important commercially, most instructionaloperating systems have not included any networking components. To address this, the capstone ofthe project is to write a signi cant and interesting distributed application. At the hardware level, we simulate the behavior a network of workstations, each running Nachos,by connecting the UNIX processes running Nachos via sockets. The Nachos operating system anduser programs running on it can communicate with other machines" running Nachos simply bysending messages into the emulated network the transmission is actually accomplished by socketsend and receive. The Nachos network provides unreliable transmission of limited-size packets frommachine to machine. The likelihood that any packet will be dropped can be set as a command-lineoption, as can the seed used to choose which packets are randomly chosen to be dropped. Packetsare dropped but never corrupted, so that checksums are not required. To demonstrate how to use the network and at the same time, how to take advantage of layering,we built a simple post o ce protocol on top of the network. The post o ce layer provides a setof mailboxes" that serve to route incoming messages to the appropriate waiting thread. Messagessent through the post o ce also contain a return address to be used for acknowlegements. The assignment is rst to implement protocol layers to provide for the reliable transmission ofarbitrary-sized messages, and then to build a distributed application on top of that service. Thefragmentation protocol is straightforward to implement | one need merely to split the message intopieces, add fragment serial numbers, and send them one by one. Reliability is more interesting,requiring a careful analysis and design to be implemented correctly. The choice of how to complete the project is left up to the students creativity. We did make afew suggestions: multi-user UNIX talk, a distributed le system with caching, a process migrationfacility, distributed virtual memory, a gateway protocol that is robust to machine crashes. Perhapsthe most interesting application a student built was a distributed version of the battleship" game, 7
  8. 8. with each player on a di erent machine. This illustrated the role of distributed state, since eachmachine kept only its local view of the gameboard it also exposed several performance problems inour hardware simulation code which we have since xed. Perhaps the biggest limitation of our current implementation is that we do not model networkperformance correctly, because we do not keep the timers on each of the Nachos machines synchro-nized with one another. There are well-known ways of doing this Chandy & Misra 1981, Je ersonet al. 1987], but we have not implemented one of them yet. With this, we would have been able toinclude a benchmark of the students network protocols it would also allow students to implementa parallel algorithm (albeit using message-passing) as the nal part of the project.4 Lessons LearnedDesigning and implementing Nachos taught us a lot about how instructional software should be puttogether, and provided insights on how students learn about complex systems. In this section, wediscuss some of the lessons that we learned. In devising the assignments, we had to decide which pieces of the Nachos code to provide studentsand which pieces to leave for students to write themselves. At one extreme, we could have providedstudents only the hardware simulation routines, leaving a tabula rasa for students to build an entireoperating system from scratch. This seemed impractical, given the scope of what we wanted studentsto achieve during the semester. Thus, when we taught the course for the rst time, our goal was to provide students with themundane and/or technically di cult parts of the operating system, such as generic list and bitmapmanagement routines on the one hand, and low level thread context switch code on the other. Wedid this by writing the entire operating system from scratch, and then ripping out the parts that wethought students should write for themselves. We found, however, that code (if simple enough), can be very useful at illustrating how somepiece of the operating system should behave. The key is that the code has to be able to runstandalone, without further e ort on the part of students. Our thread system, although limited,could show exactly what happens when one thread relinquishes a processor to another thread. Bycontrast, when we provided students with less than a working le system, students had di cultyunderstanding how the pieces of the le system t together. Similarly, we initially left to studentsthe de nition of the system call interface, including how parameters were to be passed from usercode to the kernel. A simple example would have largely eliminated the resulting confusion. Of course, reading code by itself can be a boring and pointless exercise we addressed this bykeeping our code as simple as possible, and by asking students to modify it in fairly fundamentalways. The result is that the assignments focus on the more interesting aspects of operating systems,where tradeo s exist so that there is no single right answer. Another lesson that we learned from using Nachos for a semester was the need to add a quanti-tative aspect to the assignments. We explicitly encouraged students to implement simple solutionsto the assignments, to avoid sprawling complexity. But because we initially had no standard bench-marks for measuring the performance of student implementations, we had no counterbalance to showwhen complexity was justi ed. Students tended to devise overly simplistic solutions, where only abit more e ort was needed to be realistic. We hope that the performance tests that weve added 8
  9. 9. will encourage students to identify which added complexity is justi ed by its bene ts.5 ConclusionsWe have written an instructional operating system, called Nachos. It is designed to take advantageof advances in hardware and software technology, and to illustrate the principles of modern operatingsystems. These include concurrency, caching, and distributed computation. We have used Nachosfor one semester in the undergraduate operating systems course at Berkeley, and the results werepositive. We plan to use Nachos in future semesters, and we have made it publicly available in thehope that others will also nd it useful.6 AcknowledgementsWe would like to thank the Spring 1992 CS 162 class at Berkeley for serving as guinea pigs whileNachos was under development. We would also like to thank Brian Bershad, Ed Lazowska, JohnOusterhout, and Dave Patterson for their very helpful advice during the design of Nachos JohnOusterhout also wrote the MIPS simulator that we used. We credit Lance Berc with the acronymfor Nachos: Not Another Completely Heuristic Operating System.ReferencesAguirre et al. 1991] Aguirre, G., Errecalde, M., Guerrero, R., Kavka, C., Leguizamon, G., Printista, M., and Gallard, R. Experiencing MINIX as a Didactical Aid for Operating Systems Courses. Operating Systems Review, 25:32{39, July 1991.Anderson et al. 1989] Anderson, T., Lazowska, E., and Levy, H. The Performance Implications of Thread Management Alternatives for Shared Memory Multiprocessors. IEEE Transac- tions on Computers, 38(12):1631{1644, December 1989.Bedichek 1990] Bedichek, R. Some E cient Architecture Simulation Techniques. In Proceedings of the 1990 USENIX Winter Conference, pp. 53{63, January 1990.Birrell 1989] Birrell, A. An Introduction to Programming with Threads. Technical Report #35, Digital Equipment Corporations Systems Research Center, Palo Alto, California, January 1989.Chandy & Misra 1981] Chandy, K. and Misra, J. Asynchronous Distributed Simulation via a Se- quence of Parallel Computations. Communications of the ACM, 24(11):198{206, Novem- ber 1981.Daley & Dennis 1968] Daley, R. and Dennis, J. Virtual Memory, Processes and Sharing in MUL- TICS. Communications of the ACM, 11(5):306{312, May 1968. 9
  10. 10. Dijkstra 1989] Dijkstra, E. On the Cruelty of Really Teaching Computer Science. Communications of the ACM, 32(12):1398{1404, December 1989.Holt 1983] Holt, R. Concurrent Euclid, the UNIX System, and TUNIS. Addison-Wesley, 1983.Je erson et al. 1987] Je erson, D., Beckman, B., Wieland, F., Blume, L., DiLoreto, M., Hontabas, P., Laroche, P., Studevant, K., Tupman, J., Warren, V., Wedel, J., Younger, H., and Bellenot, S. Distributed Simulation and the Time Warp Operating System. In Proceedings of the 11th ACM Symposium on Operating Systems Principles, pp. 77{93, November 1987.Kane 1987] Kane, G. MIPS R2000 RISC Architecture. Prentice Hall, 1987.Lam et al. 1991] Lam, M., Rothberg, E., and Wolf, M. The Cache Performance and Optimizations of Blocked Algorithms. In Proceedings of the 4th International Conference on Architectural Support for Programming Languages and Operating Systems, pp. 63{74, April 1991.Lampson & Redell 1980] Lampson, B. and Redell, D. Experiences with Processes and Monitors in Mesa. Communications of the ACM, 23(2):104{117, February 1980.Le er et al. 1989] Le er, S., McKusick, K., Karels, M., and Quarterman, J. Design and Imple- mentation of the 4.3 BSD Unix Operating System. Addison-Wesley, 1989.Levy & Lipman 1982] Levy, H. and Lipman, P. Virtual Memory Management in the VAX/VMS Operating System. Computer, pp. 35{41, March 1982.Lions 1977] Lions, J. A Commentary on the UNIX Operating System, June 1977. Department of Computer Science, University of New South Wales.McKusick et al. 1984] McKusick, M., Joy, W., Le er, S., and Fabry, R. A Fast File System for UNIX. ACM Transactions on Computer Systems, 2(3):181{197, August 1984.Mealy et al. 1966] Mealy, G., Witt, B., and Clark, W. The Functional Structure of OS/360. IBM Systems Journal, 5(1):3{51, January 1966.Mundie & Fisher 1986] Mundie, D. and Fisher, D. Parallel Processing in Ada. IEEE Computer Magazine, 19(8):20{25, August 1986.Nelson 1991] Nelson, G., editor. Systems Programming with Modula-3. Prentice Hall, 1991.Patterson 1992] Patterson, D. Has CS Changed in 20 Years? Computing Research News, 4(2):2{3, March 1992.Ritchie & Thompson 1974] Ritchie, D. and Thompson, K. The Unix Time-Sharing System. Com- munications of the ACM, 17(7):365{375, July 1974.Rosenblum & Ousterhout 1992] Rosenblum, M. and Ousterhout, J. The Design and Implementa- tion of a Log-Structured File System. ACM Transactions on Computer Systems, 10(1):26{ 52, February 1992. 10
  11. 11. Tanenbaum 1987a] Tanenbaum, A. Operating Systems: Design and Implementation. Prentice-Hall, 1987.Tanenbaum 1987b] Tanenbaum, A. A UNIX Clone with Source Code for Operating Systems Courses. Operating Systems Review, 21(1):20{29, January 1987.Wulf et al. 1974] Wulf, W., Cohen, E., Corwin, W., Jones, A., Levin, R., Pierson, C., and Pollack, F. HYDRA: The Kernel of a Multiprocessor Operating System. Communications of the ACM, 17(6):337{344, June 1974. 11