Mach (kernel)
Mach (/mɑːk/)[1] is a kernel developed at Carnegie Mellon University by Richard Rashid and Avie Tevanian to support operating system research, primarily distributed and parallel computing. Mach is often considered one of the earliest examples of a microkernel. However, not all versions of Mach are microkernels. Mach's derivatives are the basis of the operating system kernel in GNU Hurd and of Apple's XNU kernel used in macOS, iOS, iPadOS, tvOS, and watchOS.
Developer(s)
1985
The project at Carnegie Mellon ran from 1985 to 1994,[2] ending with Mach 3.0, which is a true microkernel. Mach was developed as a replacement for the kernel in the BSD version of Unix, so no new operating system would have to be designed around it. Mach and its derivatives exist within a number of commercial operating systems. These include all using the XNU operating system kernel which incorporates an earlier non-microkernel Mach as a major component. The Mach virtual memory management system was also adopted in 4.4BSD by the BSD developers at CSRG,[3] and appears in modern BSD-derived Unix systems such as FreeBSD.
Mach is the logical successor to Carnegie Mellon's Accent kernel. The lead developer on the Mach project, Richard Rashid, has been working at Microsoft since 1991; he founded the Microsoft Research division. Another of the original Mach developers, Avie Tevanian, was formerly head of software at NeXT, then Chief Software Technology Officer at Apple Inc. until March 2006.[4][2]
History[edit]
Name[edit]
The developers had to bike to lunch through rainy Pittsburgh's mud puddles, and Tevanian joked the word "muck" could form a backronym for their Multi-User (or Multiprocessor Universal) Communication Kernel. Italian CMU engineer Dario Giuse[5] later asked project leader Rick Rashid about the project's current title and received "MUCK" as the answer, though not spelled out but just pronounced: IPA: [mʌk] which he, according to the Italian alphabet, wrote like Mach. Rashid liked Giuse's spelling "Mach" so much that it prevailed.[6]: 103
Unix pipes[edit]
A key concept in the original Unix operating system was the idea of a pipe. A pipe was an abstraction that allowed data to be moved as an unstructured stream of bytes from program to program. Using pipes, users (or programmers) could link together multiple programs to complete tasks, feeding data through several small programs in turn. This contrasted with typical operating systems of the era, which required a single large program that could handle the entire task, or alternately, used files to pass data, which was resource expensive and time-consuming.
Pipes were built on the underlying input/output system. This system was, in turn, based on a model where drivers were expected to periodically "block" while they waited for tasks to complete. For instance, a printer driver might send a line of text to a line printer and then have nothing to do until the printer completed printing that line. In this case, the driver would indicate that it was blocked, and the operating system would allow some other program to run until the printer indicated it was ready for more data. In the pipes system the limited resource was memory, and when one program filled the memory assigned to the pipe, it would naturally block. Normally this would cause the consuming program to run, emptying the pipe again. In contrast to a file, where the entire file has to be read or written before the next program can use it, pipes made the movement of data across multiple programs occur in a piecemeal fashion without any programmer intervention.
However, implementing pipes in memory buffers forced data to be copied from program to program, a time-consuming and resource intensive operation. This made the pipe concept unsuitable for tasks where quick turnaround or low latency was needed, such as in most device drivers. The operating system's kernel and most core functionality was instead written in a single large program. When new functionality, such as computer networking, was added to the operating system, the size and complexity of the kernel grew, too.
New concepts[edit]
Unix pipes offered a conceptual system that could be used to build arbitrarily complex solutions out of small interacting programs. These smaller programs were easier to develop and maintain, and had well-defined interfaces that simplified programming and debugging. These qualities are even more valuable for device drivers, where small size and bug-free performance are extremely important. There was a strong desire to model the kernel itself on the same basis of small interacting programs.
One of the first systems to use a pipe-like system underpinning the operating system was the Aleph kernel developed at the University of Rochester. This introduced the concept of ports, which were essentially a shared memory implementation. In Aleph, the kernel itself was reduced to providing access to the hardware, including memory and the ports, while conventional programs using the ports system implemented all behavior, from device drivers to user programs. This concept greatly reduced the size of the kernel, and allowed users to experiment with different drivers simply by loading them and connecting them together at runtime. This greatly eased the problems when developing new operating system code, which otherwise generally required the machine to be restarted. The general concept of a small kernel and external drivers became known as a microkernel.
Aleph was implemented on Data General Eclipse minicomputers and was tightly bound to them. This machine was far from ideal, since it required memory to be copied between programs, which involved a considerable performance overhead. It was also quite expensive. Nevertheless, Aleph proved that the basic system was sound, and went on to demonstrate computer clustering by copying the memory over an early Ethernet interface.
Around this time a new generation of central processors (CPUs) were coming to market, offering 32-bit address spaces and (initially optional) support for a memory management unit (MMU). The MMU handled the instructions needed to implement a virtual memory system by keeping track of which pages of memory were in use by various programs. This offered a new solution to the port concept, using the copy on write mechanism provided by the virtual memory system. Instead of copying data between programs, all that had to be sent was the data needed to instruct the MMU to provide access to the same memory. This system would implement the interprocess communications system with dramatically higher performance.
This concept was picked up at Carnegie-Mellon, who adapted Aleph for the PERQ workstation and implemented it using copy-on-write. The port was successful, but the resulting Accent kernel was of limited practical use because it did not run existing software. Moreover, Accent was as tightly tied to PERQ as Aleph was to the Eclipse.
Mach[edit]
The major change between these experimental kernels and Mach was the decision to make a version of the existing 4.2BSD kernel re-implemented on the Accent message-passing concepts. Such a kernel would be binary compatible with existing BSD software, making the system immediately useful for everyday use while still being a useful experimental platform. Additionally, the new kernel would be designed from the start to support multiple processor architectures, even allowing heterogeneous clusters to be constructed. In order to bring the system up as quickly as possible, the system would be implemented by starting with the existing BSD code, and re-implementing it bit by bit as inter-process communication-based (IPC-based) programs. Thus Mach would begin as a monolithic system similar to existing UNIX systems, and evolve more toward the microkernel concept over time.[4]
Mach started largely being an effort to produce a cleanly defined, UNIX-based, highly portable Accent. The result is a short list of generic concepts:[7][8]