banner
MIG

MIG

Angelos·MIG·Trubetskoy

The Story Behind Mac OS X Three

Father of Mach Avie Tevanian#

Text by Wang Yue

In 1975, at the University of Rochester in New York, a group of researchers was working on a project called RIG (Rochester’s Intelligent Gateway), designed and led by Jerry Feldman. The goal of RIG was to provide a unified access method for all local and remote computing devices (such as disks, printers, tapes, plotters, etc.), and its operating system was called Aleph.

Jerry Feldman.jpg
Jerry Feldman

To achieve the required functionality, the core of Aleph primarily built an Interprocess Communication (IPC) mechanism. The processes of RIG could send messages to each other as long as they set the target port. A few years later, the RIG project was deemed a failure, mainly due to the lack of many useful features, such as the absence of a protection mechanism for ports, a maximum message size of only 2KB (due to hardware limitations), and poor network support. However, in the 1970s, this system still represented the advanced level of operating system design at the time. For instance, in addition to IPC, each process had memory protection, which was enough to make Apple, a company that had not implemented memory protection technology by the late 1990s, feel embarrassed.

Rochester’s Intelligent Gateway.jpg
Reports on the system at the time

The project later failed, and in 1979, Dr. Richard Rashid from RIG graduated to become a professor at Carnegie Mellon University, where he began the Accent project. It was a network operating system that started active development in April 1981. Influenced by RIG, the highlight of the Accent system was its use of IPC, and it addressed many of RIG's shortcomings. For example, each process had 4GB of virtual memory space, and even the kernel itself could be stored in cache pages. The memory had advanced Copy-on-Write functionality, enabling the transfer of large information between processes. Readers can understand Accent as a RIG kernel that supports virtual memory technology and has network-transparent IPC functionality.

Richard Rashid.jpg
Richard Rashid

However, after a few years, developers began to lose interest in Accent. In the early 1980s, many believed that multi-core computing was the trend for the future of computers, but the Accent kernel did not consider these issues during its design. Moreover, as many laboratories began to purchase more powerful computers, it meant that Accent needed to be ported to new target architectures. Additionally, Unix was becoming increasingly popular, both in operating system theory and in user programs, and Accent was not a Unix system, so it could not enjoy many of the benefits of the Unix world. To address this issue, researchers decided to completely overturn all designs, leading to the creation of a brand new system.

On a rainy day in Pittsburgh, Avie Tevanian, the primary developer of this system at Carnegie Mellon University, was walking with classmates to lunch while holding an umbrella. As they navigated around numerous mud puddles, they brainstormed names for the new system. Inspiration struck, and Avadis Tevanian suggested calling the system Muck, which made his classmates laugh heartily. Later, when Richard Rashid and an Italian colleague, Dario Giuse, mentioned this joke, the colleague inadvertently typed Muck as Mach, causing Richard Rashid to burst into laughter, and thus the great Mach system was named.

Avie Tevanian2.jpg
Avie Tevanian

Mach is a Unix-compatible system inspired by Accent. That year, Unix was already sixteen years old and remained the main battlefield for operating system theory and practical development. The Unix kernel became increasingly complex due to the addition of new features. One of Mach's main goals was to reduce the various services of Unix as much as possible to simplify and maintain the kernel. The project started in 1984, with the main goal of including complete multitasking support, good hardware portability, and moving many services out of the kernel to run as services on top of the kernel, while providing compatibility with Unix.

Mach was written in pure C, which ensured a certain degree of portability, providing an important premise for the later NeXT's port to PowerPC and the 2005 port to Intel. To reduce the tasks the kernel had to manage, Mach was very strict, providing only memory and processor management. Functions like file systems, networking, and input/output were executed as individual system processes, running independently above the kernel.

Mach 对多处理器的支持.png
Mach's support for multiprocessors

The development process of Mach started with 4.3BSD, referenced Accent from RIG, and adopted DEC's virtual memory design ideas, gradually developing and replacing BSD's code with newly written code. Two years later, in 1986, although the system services could not be completely separated from the kernel, significant progress was made. The first version of Mach was completed, and the team published a conference paper, becoming a milestone classic in the history of operating systems, sparking a "microkernel" trend in the operating system industry. This paper has been cited over twelve hundred times in twenty-five years.

文章.png
The paper

This article mainly discussed two aspects: IPC and virtual memory. In terms of IPC, Mach divided the complex message-passing mechanism into four independent and clear concepts: task, thread, port, and information. A task is an object that owns a set of system resources, allowing threads to execute within it; a thread is the basic unit of execution, possessing the context of a task and sharing resources within the task. Due to the influence of this paper, the project received investments from many organizations, including OSF (Open Software Foundation).

Mach.jpg
Several basic abstractions of Mach

Of course, there is always a gap between academia and engineering, so even the most popular Mach 2.5 was still a single kernel that included most of the BSD service layer. However, many operating systems, including NeXTSTEP and OSF/1, adopted Mach as their kernel technology because many researchers still believed that microkernels represented the future.

Although the efficiency of Mach 2.5 was slightly lower than that of traditional Unix systems, researchers remained calm because Mach supported multiprocessor systems and could process tasks quickly using multithreading. In contrast, other Unix kernels did not have complete support for multiprocessors, so the slightly lower efficiency of Mach was entirely acceptable. However, with the advent of the Mach 3 microkernel, which completely separated Mach from BSD services, researchers could no longer remain calm. After the separation of services and the kernel, the number of IPCs between tasks skyrocketed. A simple Unix system call involved more than a dozen operations, including opening ports, setting permissions, sending, and receiving messages. Even using hardware from 1997, which was several years later, running a system call-intensive program on Mach was 50% slower than on a typical Unix system, and there was no good way to solve this problem.

Thus, after Mach 3 was released, although a few microkernel believers continued to stubbornly improve Mach or began research on other microkernels like L4, interest in Mach in academia significantly declined, and Mach 3 became the last version. After the project disbanded, Richard Rashid went to Microsoft Research.

Returning to our protagonist Avie Tevanian, he graduated with a Ph.D. in 1987 and joined NeXT. This company had just been founded by Steve Jobs two years earlier, during which Steve Jobs had done nothing substantial, only spending $100,000 to hire Paul Rand to design a company logo. It was not until Avie Tevanian joined that the company began to take action. In 1987, the company confirmed it would develop a computer workstation for researchers, and thus the development of hardware and software began in earnest. The hardware team was led by Rich Page, who had previously led Apple Lisa, while Avie Tevanian was responsible for software, planning to develop a graphical user interface operating system called NeXTSTEP. Since Avie Tevanian was the main developer of Mach, it was natural that NeXTSTEP was based on Mach. On October 12, 1988, NeXT released a preview version (version 0.8) and released version 1.0 on September 18, 1989.

NeXTSTEP 系统.jpg
NeXTSTEP System

As the kernel of the NeXTSTEP system, the NeXT branch of Mach underwent many changes. NeXTSTEP 0.8 mainly used Mach version 2.0, while the later NeXTSTEP 1.0 version was primarily based on Mach version 2.5, including a custom service layer based on the latest 4.3BSD at the time.

Starting from version 3.1, the NeXT branch of Mach also included a brand new device driver framework called DriverKit, which was only for x86 hardware. Unlike Mach and BSD code, DriverKit was written in Objective-C. Why an object-oriented language? Looking at the DriverKit documentation for NeXTSTEP 3.3, readers may find that NeXTSTEP understood all hardware devices as objects. We know that there are inheritance relationships between objects; for example, a disk (IODisk object) is a subclass of input/output devices (IODevice object), while the disk (IODisk) itself is a parent object of logical disks (IOLogicalDisk). Hardware initialization corresponds to the initialization of each object (init method), and hardware has read and write capabilities, so getter/setter methods can be used. Therefore, DriverKit is a very distinctive implementation. Moreover, since Objective-C is highly efficient and has few dependencies (Objective-C programs can be directly compiled into equivalent C programs, and the Objective-C runtime library libobjc is also known for its efficiency), it was also a good choice for writing drivers. A few years later, IOKit was essentially a copy of DriverKit.

At this point, the NeXTSTEP operating system was a great success, and venture capitalists were eager to buy in, but the hardware never sold well1, so NeXT cut its hardware department to focus solely on software, which further propelled NeXTSTEP to its peak, supporting hardware like 68K, x86, PA-RISC, and SPARC. Interestingly, it did not support the PowerPC architecture. It could generate a binary file containing executable code for all architectures, allowing developed programs to run on all platforms. This feature also influenced the technology of later Mac OS X. During the Mac OS X 10.4 era, two epoch-making things happened: one was that Apple produced a 64-bit Power Mac, allowing developers to release a single executable file containing both 64-bit and 32-bit programs without requiring users to distinguish between them; the other was collaboration with Intel. Apple officially announced Universal Binary technology, allowing a Mach-O file to contain instructions for both Intel and PowerPC. This thoughtful design (considering that most computer users have no idea about Intel, PowerPC, 64-bit, 32-bit technologies) came from Mach's technology.

Mac OS X 架构图.jpg
Mac OS X Architecture Diagram

After NeXTSTEP 3.3, NeXTSTEP was renamed OPENSTEP due to the collaboration between NeXT and Sun, and version 4.0 was released in 1996. By February 4, 1997, when NeXT was acquired by Apple, the kernel improvements during this period, aside from syncing the source code to Mach 3.0, are unclear. Moreover, for unknown reasons, I could not find the release notes and programming documentation for DriverKit in the official version of OPENSTEP on the CD I have, so I will not elaborate on that. However, during this time, Apple's activities are worth mentioning. Previously, in "Linus Torvalds' Shortsightedness," we mentioned that in 1996, Apple collaborated with OSF to port Mach to PowerPC Macs and run Linux as a single service on Mach. This project was called MkLinux. A preview version based on Mach 3.0 and Linux 1.3 was released in 1996 and updated until 2002, making significant contributions to the portability of Mach on PowerPC. This PowerPC version of Mach was called the osfmk branch, which is the branch used in today's Mac OS X. Of course, many modifications were made after NeXT was merged.

mklinux.jpg
Mklinux System

After Apple acquired NeXT, Mach was confirmed as the core of the future operating system. Avie Tevanian was appointed president of the software development department. As the call to merge all projects sounded, the upper-level OpenStep API and components of the old Mac OS began to merge, and Mach also underwent significant changes. On one hand, Mach used the osfmk branch but still included 4.3BSD services; on the other hand, DriverKit was replaced by IOKit. This was a rather passive step for Apple. At that time, there was widespread skepticism about Objective-C, forcing Apple to revert to the old Mac OS API path. Apple itself was also quite unconfident about Objective-C, even considering switching to Java (we will discuss this period of insecurity later). Therefore, IOKit was a C-based driver architecture to cater to public taste. These changes first appeared in Rhapsody (we will also have a special issue on Rhapsody later). However, since C is a daunting language, Apple also trimmed C, removing multiple inheritance, templates, runtime dynamics, and exceptions, allowing developers to use this Clean C, which was a mere rebranding for Objective-C, to write drivers. But to be fair, IOKit had many improvements over DriverKit, such as allowing drivers to run in user space (although most still ran in kernel space), so a driver crash would not crash the system. Additionally, IOKit considered trends in computer development, thus performing better in power management, plug-and-play, and dynamic loading.

However, as you know, C programs require a dedicated runtime library to run, so Mach also added a library called libkern responsible for C-related functions, along with a libsa library providing basic algorithms like binary search and sorting. Finally, there was also a library called pexpert (Platform Expert) related to hardware, responsible for collecting hardware device lists, detecting machine types (such as processor speed), parsing boot parameters, and other miscellaneous tasks.

At this point, the kernel of Mac OS X was fully formed, establishing a tripartite structure of BSD, IOKit, and Mach osfmk, with pexpert, libkern, and libsa as the foundation. Apple named its kernel XNU. Its code is open source 2. Since 4.3BSD was already a thing of the past, Apple later invested significant resources to support FreeBSD development. In 2001, Apple brought in Jordan Hubbard, the initiator and leader of FreeBSD, and by Mac OS X 10.3, it had basically synced to FreeBSD 5's code.

XNU 内核演变.jpg
Evolution of the XNU Kernel

Additionally, Apple's development also fed back into the FreeBSD group, including the introduction of AUDIT (man audit) in the FreeBSD 6.2 kernel3, the later introduction of libdispatch in FreeBSD 8 (this technology, called Grand Central Dispatch by Apple, was a major new feature promoted in Mac OS X 10.6, and FreeBSD essentially had this latest technology when Mac OS X 10.6 was released), and LLVM-Clang in FreeBSD-CURRENT, all of which were contributions from Apple. Since 1999, the FreeBSD source repository has contained numerous patches and new features provided by Apple.

Early versions of Mac OS X were quite unstable, leading to kernel crashes. Version 10.0 would directly output backtrace information like Linux or BSD, which was not very aesthetically pleasing, so starting from version 10.2, Apple designed a multilingual image to inform users that their kernel had crashed, making the kernel crash appear a bit more elegant. Due to the inclusion of four languages, it was humorously referred to as the “Four Nations” by domestic users, which is a feature of the Mach osfmk part of XNU. However, starting from versions 10.3-10.4, the system became increasingly stable, and kernel crashes became rare during normal use. Moreover, the services provided by the kernel increased, making Mac OS X a complete system.

四国语言.jpg
The famous "Four Nations," now expanded to six

The most significant changes to the XNU architecture in the 21st century included support for PPC64 (during version 10.4), x86 architecture (which had always been supported, to be discussed in detail during Apple's Intel transition), x86_64 (64-bit support was gradually developed by Apple over the years. In the 10.4 era, the 32-bit kernel supported loading 64-bit user programs; the 10.5 system provided a 64-bit Cocoa framework, but most system programs were still 32-bit; in the 10.6 era, the kernel supported booting in 64-bit mode, but this was not the default on many hardware configurations, although many system programs had been rewritten and compiled as 64-bit binaries; in the 10.7 era, the kernel booted by default in 64-bit mode), and ARM architecture (the XNU kernel is used in iPhones and iPads). The support for ARM architecture is particularly significant. However, on May 31, 2006, the accomplished Avie Tevanian left Apple for other opportunities, just under a year before the iPhone miracle occurred at Apple.

The author of this article, Wang Yue, is a graduate student in the Computer Science Department at the University of Pennsylvania, a well-known TeX developer in China, and a lesser-known OpenFOAM developer.

Professor Wang Yue is one of the people I admire the most. This series of articles has been published for over ten years, and there are hardly any complete versions available online. I hope to further improve upon this foundation so that more people can learn about it.

References:

Footnotes#

  1. See Aaron Hillegass's "Cocoa Programming for Mac OS X" preface

  2. Readers can visit https://opensource.apple.com/source/xnu/xnu-123.5/ where each part's code is stored in a separate folder, clearly organized, and worth a read.

  3. See https://www.freebsd.org/releases/6.2R/announce/

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.