Mach

**Mach**（國際音標：[mʌk]）是一個由卡內基梅隆大學開發的電腦作業系統微核心，為了用於作業系統之研究，特別是在分散式與並列運算上。是最早實現微核心作業系統的例子之一，是許多其它相似的計畫的標準。

Mach 開發計畫在卡內基梅隆大學從 1985 年運行到 1994 年，到 Mach 3.0 版結束。其他還有許多人繼續 Mach 的研究包括猶他大學的 Mach 4 （頁面存檔備份，存於網際網路檔案館）。Mach 的開發是為了取代 BSD 的 UNIX 核心，所以是許多新的作業系統的設計基礎。Mach 的研究至今似乎是停止了，雖然有許多商業化作業系統，如 NEXTSTEP 與 OPENSTEP，特別是 Mac OS X（使用 XNU 核心）都是使用 Mach 或其衍生系統。Mach 的虛擬記憶體（VM）系統也被 BSD 的開發者用於 CSRG，並出現在 BSD 衍生的系統中，如 FreeBSD。Mac OS X 與 FreeBSD 並未保留 Mach 首倡的微核心結構，除了 Mac OS X 繼續提供微核心於內部處理通訊以及應用程式直接控制。

Mach 繼承卡內基梅隆大學的 Accent kernel，Mach 計畫主導人理察・拉希德曾於微軟的研究部門擔任高級人員，後成為微軟副總裁。另一 Mach 開發者阿瓦德斯・特凡尼安（Avie Tevanian）曾是 NeXT 首席程式設計師，之後擔任蘋果電腦軟體技術部門主管直到 2006 年 [1] （頁面存檔備份，存於網際網路檔案館） 。

一個名為 GNU Mach 的計劃與其相關，它是 GNU 作業系統工程的一部分。已有的作業系統 Debian GNU/Hurd 便是基於 GNU Mach 及其上的 GNU Hurd。

## 歷史

### 名稱起源

### Mach 概念

Mach 是作為傳統 UNIX 核心的替代品出現的，因此其間的不同之處值得留意。當時的人們已漸漸感受到了早期 UNIX 中「一切皆檔案」的抽象機制的不足，有限的擴充性使得開發者捉襟掣肘，苦不堪言。雖說貝爾實驗室的 Plan9 在此方向上做了進一步努力，可是效果並不理想。現代作業系統需要更進一步的抽象。

比如 UNIX 的管道可謂飽受爭議。人們迫切需要一個類似管道的機制，允許在程式間交換不同的資料，而不僅僅是檔案式的讀寫。或者換句話說，一套行程間通訊機制（IPC）。一時間各路系統（包括 UNIX）紛紛推出了各自的 IPC 機制，然而大多皆是些針對特定目標的庫，其通用性仍遠遠不夠。

鑑於此，卡耐基梅隆大學從 Accent 核心專案出發，嘗試開發了一套基於共享記憶體的 IPC 系統。Accent 是一個擁有豐富特性的純實驗系統，不過在 Accent 開發期間，社會上研究作業系統的重點已經有所變化；且 UNIX 已經被廣泛接受作為研究的預設系統，Accent 對 UNIX 的不相容也限制了它在研究方向上的應用；更甚者，Accent 的可移植性似乎並不是很好，而在當時看來（八十年代初）硬體平台的更新換代值正欣欣向榮，似乎會出現一次大爆炸。

因此卡內基梅隆大學轉向了 Mach 專案，其設計目標大體即一個結構清晰、UNIX 相容、高度可移植的 Accent。按以下幾個概念作為其基礎：

* 「任務」即擁有一組系統資源的物件，允許「執行緒」在其中執行。
* 「執行緒」是執行的基本單位，擁有一個任務的上下文，並且共享任務中的資源。
* 「port」是任務間通訊的一組受保護的訊息佇列；任務可以對任何 port 傳送或接收資料。
* 「訊息」是某些有類型的資料物件的集合，它們只可以傳送至 port - 而非某特定任務或執行緒。

Mach 繼承了 Accent IPC 的理念，然其本身卻紮根於 UNIX，輕而易舉即可移植 UNIX 下的程式。Mach 引入了 port 的概念用以表示雙向的 IPC，它就像 UNIX 下的檔案一樣擁有權限資訊，使得其安全模型非常接近 UNIX。並且，Mach 使得任何行程都可以擁有一般系統中核心才有的權限，從而允許使用者行程實現與硬體互動等操作。

同 UNIX 一樣，Mach 系統也包含了一組豐富的實用工具，並保留了 unix 中驅動程式的概念用以硬體互動。

與 UNIX 的一大區別即在於，除了操作檔案，Mach 更可以操作一切「任務」。這一來大量的核心代碼可以轉移到使用者空間，使核心變得更小，從此領發了微核心的思潮。與傳統的系統不同，Mach 下的行程（或者說「任務」）之下是多個執行緒。這在今天自己屢見不鮮，可是要知道，Mach 正是如此定義任務與執行緒關係的第一人。核心的責任從總攬大局者精簡為基礎設施的提供者，並為其提供有限的排程。

Port 機制在 IPC 中的應用該是 Mach 與其他傳統核心的一大分野。在 UNIX 下，使用者行程呼叫核心只能通過系統呼叫或陷入（trap）。使用者行程使用一個庫安排好資料的位置，然後軟體觸發一個中斷，核心在初始化時會為所有中斷設定 handler，因此程式觸發中斷的時候，控制權就轉移到了核心，在一些必要的檢查之後即可得以進一步操作。

在 Mach 下，這就交給了 IPC 系統。與直接系統呼叫不同，這裡的使用者行程是先向核心申請一個 port 的存取許可，然後利用 IPC 機制向這個 port 傳送訊息。雖說傳送訊息的操作同樣是系統呼叫，但 Mach 核心的工作形式有些不同 ——handler 的工作可以交由其他行程實現。

IPC 訊息傳遞機制的應用為執行緒和並行提供了很好的支援。行程之下是多個執行緒，執行緒作為 IPC 機制的單元，Mach 得以在訊息被處理時控制執行緒睡眠或喚醒。這就允許系統將行程分布於多個處理器之上，訊息直接通過共享記憶體實現也可，必要時為其它處理器複製一份也可。在傳統核心中這很難實現：系統必須保證不同處理器上的的不同程式不會在同時存取同一塊記憶體，在 Mach 中則要更容易的多。不同行程的記憶體存取互不干涉，一切交由 port 通信。

早期的 IPC 系統有些效能問題，必須正視。同其前輩 Accent 一樣，Mach 使用一個共享記憶體機制以避免訊息傳遞中低效的記憶體拷貝。它利用硬體的 MMU 實現資料共享，只在資料被修改的時候才執行拷貝，即寫時複製。

核心也必須檢查訊息的正確性。Port 在設計上即取了 UNIX 檔案系統的概念，這一來就允許使用者使用現成的檔案系統概念即可，權限、存取許可之類就都有了。

這樣設計也簡化了開發。傳統的程式依然可以拿來，也可以再設計。單核心系統的一個 bug 就得讓整個系統崩潰從而不得不重新啟動，而 Mach 僅僅需要重新執行出問題的那個行程。作業系統即一組程式的集合，使用者得以選擇其系統的功能 —— 只需管理當前執行的行程即可。

需要了解，Mach 以上的所有特性皆為跨平台而設計。如下參照一段：

與 UNIX 最初無視多處理器的設計不同，Mach 在設計伊始即將多處理器支援納入考慮。它的擴充性也很好，UMA 還是 NUMA 都能很好的支援。Mach 是為千種不同的處理器而設計的，移植到其他體系結構很容易。其設計的一個關鍵目標即為各不相同的硬體平台上，實現可移植的分散式系統。（Appendix B, Operating System Concepts）

不足自然也不少。相對容易的一個問題是 port 的位置不明顯，在 UNIX 下這樣的問題通過檔案系統提供一個大家都知道的名字來解決。雖說這一機制也可以拿來，但是 Mach 在設計上又恰恰盡力使得 port 保持透明。缺乏表示 port 位置的機制，使得其擴充性大打折扣。

## 參見

* HURD
* GNU Mach
* Debian GNU/Hurd
* XNU