Linux內核

Linux內核（Linux kernel）是一種開源的類Unix作業系統宏內核。整個Linux作業系統家族基於該內核部署在傳統電腦平台（如個人電腦和伺服器，以Linux發行版的形式）和各種嵌入式平台，如路由器、無線接入點、專用小交換機、機頂盒、FTA接收器、智能電視、數字視頻錄像機、網路附加存儲（NAS）等。工作於平板電腦、智慧型手機及智能手錶的Android作業系統同樣通過Linux內核提供的服務完成自身功能。儘管於桌面電腦的占用率較低，基於Linux的作業系統統治了幾乎從行動裝置到主機的其他全部領域。截至2017年11月，世界前500台最強的超級計算機全部使用Linux。

Linux內核最早是於1991年由芬蘭黑客林納斯·托瓦茲為自己的個人電腦開發的，他當時在Usenet新聞組`comp.os.minix`登載帖子，這份著名的帖子標誌著Linux內核計劃的正式開始。如今，該計劃已經拓展到支持大量的計算機體系架構，遠超其他作業系統和內核。它迅速吸引了一批開發者和使用者，利用它作為其他自由軟體項目的核心，如著名的 GNU 作業系統。而今天，Linux 內核已接受了超過1200家公司的近12000名程式設計師的貢獻，其中包括一些知名的軟硬體發行商。

從技術上說，Linux 只是一個符合POSIX 標準的內核。它提供了一套應用程式接口（API），通過接口使用者程序能與內核及硬體交互。僅僅一個內核並不是一套完整的作業系統。有一套基於 Linux 內核的完整作業系統叫作Linux 作業系統，或是GNU/Linux（在該系統中包含了很多GNU 計劃的系統組件）。

Linux 內核是在GNU通用公共許可證第2版之下發布的（加上一些非自由固件、blob與各種非自由許可證），是一個開源項目協作的突出例子。它的版本支持根據版本最長可達6年，貢獻者遍佈世界各地，日常開發相關的討論在Linux 內核郵件列表上。

## 歷史

<image>

1991年，林納斯·托瓦茲，一名21歲的就讀於芬蘭赫爾辛基大學的電腦科學專業學生，基於一些簡單的想法，打算編寫一個作業系統內核。他通過英特爾80386彙編語言的任務切換器和一個終端驅動程序開始工作。8月25號，他在`comp.os.minix`新聞組裡發了一封帖子：

之後，許多人為這個項目貢獻了代碼。在早期，MINIX社區向 Linux 內核貢獻了代碼和想法。當時，GNU 項目已經創建了許多自由作業系統所需的組件，但是它自己的內核 GNU Hurd 尚不完整且無法使用；而BSD作業系統還沒有擺脫合法的阻礙。因此，儘管早期版本的 Linux 功能有限，但它迅速獲得了開發人員和使用者。

到1991年9月，Linux內核版本 0.01 在芬蘭大學和研究網路（FUNET）的FTP伺服器（ftp.funet.fi）上發布。它有10,239行代碼。在1991年10月，0.02版本的內核發布了。

1991年12月，0.11版本的內核發布。由於它可以由運行相同內核版本的電腦編譯，因此該版本是第一個自託管的 Linux 內核。當托瓦茲於1992年2月發布0.12版本時，他採用了 GNU 通用公共許可證（GPL），而不是以前的自行起草的許可證，原先的許可證不允許商業再分發。

1992年1月19日，第一篇文章提交給新的新聞組`alt.os.linux`出現。1992年3月31日，該新聞組更名為 `comp.os.linux`。

X Window 系統隨後被移植到Linux上，所以在1992年3月，Linux 0.95 是第一個能夠運行X的版本。從0.1x到0.9x的版本號大幅跨越是因為期望沒有大的缺失部分的版本1.0的即將出現。然而，這被證明是錯誤的。從1993年到1994年初，出現了0.99版本的15個開發版本。

1994年3月14日，Linux內核1.0.0發布，共176,250行代碼。隨後的1995年3月，有310,950行代碼的 Linux 內核1.2.0發布。

在1996年6月9日發布的 Linux內核2.0版本之後，以2.0為大版本的主要更新有如下這些：

- 1999年1月25日 - 發布Linux內核2.2.0（1,800,847行代碼）
- 1999年12月18日 - 針對2.2.13的 IBM 大型機補丁發布，允許 Linux 內核用於企業級機器
- 2001年1月4日 - 發布 Linux 內核2.4.0（3,377,902行代碼）
- 2003年12月17日 - 發布 Linux 內核2.6.0（5,929,913行代碼）

從2004年開始，發布過程發生了變化，新的內核每隔2-3個月定期發布，編號為2.6.0、2.6.1，直到2.6.39。

2011年7月21日，Torvalds宣布發布Linux內核3.0：「2.6. 的日子過去了」。與Linux 2.6.39相比，大的技術變化同版本躍升沒有關係；它標誌著內核的20周年紀念。基於時間的發布過程保持不變。

2013年6月發布的Linux內核版本3.10包含15,803,499行代碼，而2015年6月發布的4.1版本已發展到超過1950萬行代碼，由近14000名程式設計師貢獻。

### 塔能鮑姆-林納斯辯論

Linux不是微內核架構的事實曾經引起了林納斯·托瓦茲與安德魯·斯圖爾特·塔能鮑姆之間一場著名的爭論。1992年在Usenet討論群組 comp.os.minix開始了一場網路論戰，討論的主題在於作業系統架構的選擇。稍後一些著名的駭客也加入討論，如大衛·米勒、曹子德。這場辯論影響了Linux核心的設計走向。塔能鮑姆認為Linux內核採用的宏內核已經過時了，應該採取比較先進的微內核架構，引起了林納斯的反擊。

在2006年5月9日，這個主題被重新審視，並且在2006年5月12日塔能鮑姆寫了一份立場聲明。

## 架構

<image>

Linux是一個單體內核，支持真正的搶占式多任務處理（於使用者態，和版本2.6系列之後的內核態）、虛擬內存、共享庫、請求分頁、共享寫時複製可執行體（通過內核同頁合併）、記憶體管理、Internet協議族和線程等功能。

設備驅動程序和內核擴展運行於內核空間（在很多CPU架構中是ring 0），可以完全訪問硬體，但也有運行於使用者空間的一些例外，例如基於FUSE/CUSE的文件系統，和部分UIO。多數人與Linux一起使用的圖形系統不運行在內核中。與標準單體內核不同，Linux的設備驅動程序可以輕易的配置為內核模塊，並在系統運行期間可直接裝載或卸載。也不同於標準單體內核，設備驅動程序可以在特定條件下被搶占；增加這個特徵用於正確處理硬體中斷並更好的支持對稱多處理。出於自願選擇，Linux內核沒有二進位內核接口。

硬體也被整合入文件層級中。使用者應用到設備驅動的接口是在/dev或/sys目錄下的入口文件。進程信息也通過/proc目錄映射到文件系統。

### 編程語言

Linux是用C語言中的GCC版（這種C語言有對標準C進行擴展）寫的，還有幾個用組合語言（用的是GCC的"AT&T風格"）寫的目標架構短段。因為要支持擴展的C語言，GCC在很長的時間里是唯一一個能正確編譯Linux的編譯器。有許多其他的語言用在一些方面上，主要集中在內核構建過程中（這裡指從源代碼創建可啟動鏡像）。包括Perl、Python和多種腳本語言。有一些驅動可能是用C++、Fortran或其他語言寫的，但是這樣是強烈不建議的。

### 編譯器兼容性

GCC是Linux內核原始碼的預設編譯器。在2004年，Intel主張通過修改內核，以便Intel C++編譯器能正確編譯內核。在2009年，有通過修改內核2.6.22版而成功編譯的報告（並帶來平均8-9%效能增長）。

自從2010年，已經開始進行使用Clang建造Linux內核的努力，Clang是一個可作為替代的C語言編譯器；截止2014年4月12日，官方內核幾乎可以完全用Clang編譯。致力於這個目標的計劃叫做「LLVMLinux」，得名於Clang所基於的LLVM編譯器下部構造。LLVMLinux不意圖複製Linux內核或LLVM，因此它是由最終提交給上游計劃的補丁構成的一個元計劃。使Linux內核可以用Clang編譯最大的好處是比GCC有更快的編譯速度，內核開發者可以得益於由此而來的更快的工作流程。

### 接口

<image>

符合標準是Linux內核內部的普遍策略。另一個規則是Linux內核主線不接受只由專有使用者空間軟體使用的內核模塊。

#### 內核至使用者空間API

<image>

原始碼可移植性確保符合標準的C程序可以在符合同樣標準的任何系統上編譯和運行。Linux內核開發、GNU C函數庫和相關的實用工具致力於追隨POSIX和單一UNIX規範。Linux內核API是內核的系統調用接口。

#### 內核至使用者空間ABI

二進位可移植性將保證任何程序在符合標準的給定硬體平台上一旦編譯通過，可以在符合同樣標準的任何其他硬體平台上以編譯後的形式運行。二進位可移植性是在基於Linux內核的作業系統上建造獨立軟體供應商（ISV）應用有商業可行性的本質要求。現有唯一的二進位兼容標準是Linux標準規範（LSB）。

#### 內核內API

<image>

在不同子系統間使用了數個內核內部API。其中一些是跨越多個發行版保持穩定的，另一些則不然。對於內核內API不作擔保。維護者和貢獻者可以在任何時候增加或變更它們。

內核內API的例子包括針對下列類別設備驅動程序的軟體框架/API：

- Video4Linux – 用於影片捕捉硬體。
- 高級Linux聲音體系（ALSA） – 用於音效卡。
- New API – 用於網路接口控制器。
- 直接渲染管理器 – 用於圖形加速器。
- KMS驅動器 – 用於影片顯示控制器。
- mac80211 – 用於無線網絡接口控制器。

#### 內核內ABI

Linux內核開發者選擇不維護穩定的內核內ABI。

### 技術特性

#### 搶占式調度系統

<image>

Linux內核提供在特定條件下的搶先式調度。直到內核版本2.4，只有使用者進程是搶先式的，就是說除了時間片用盡，在使用者模式下執行的當前進程，如果有更高態優先級的進程進入`TASK_RUNNING`狀態，它就會被中斷。自從2.6系列Linux內核，增加了中斷執行內核代碼的任務的能力，但不是對於內核代碼的所有段落。

Linux內核含有不同的調度器類。內核預設使用的調度機制叫做完全公平調度器，它介入於內核版本2.6.23。這個預設調度器類在內部也叫做`SCHED_OTHER`，而內核還含有兩個遵循POSIX的實時調度類，分別叫做`SCHED_FIFO`（實時先進先出）和`SCHED_RR`（實時輪流式），二者都優先於預設類。

通過使用實時Linux內核補丁`PREEMPT_RT`，可以支持對關鍵段落、中斷處理器和「中斷禁用」代碼序列的完全搶先。實時Linux內核補丁部分地集成入主線內核已經帶給它一些功能。搶先機制改善延遲、增進響應性，並使得Linux更加適合桌面和實時應用。老版本內核有所謂的巨鎖，用於鎖定粒度為整個內核的同步，它最終由Arnd Bergmann在2011年移除了。

還有叫做`SCHED_DEADLINE`的調度策略，實現了最近截止期限最先（EDF）演算法，它增加於2014年3月30日發行的內核版本3.14。

#### 可移植性

<image>

儘管林納斯·托瓦茲的初衷不是使Linux成為一個可移植的作業系統，今天的Linux卻是全球被最廣泛移植的作業系統內核。從行動電話到超級電腦，甚至於有人成功的將Linux內核在索尼出品的遊戲機PS2及PS3和微軟出品的遊戲機Xbox上使用。Linux也是IBM超級計算機Blue Gene的作業系統。直至2011年11月，全球前五百大超級電腦（TOP500）有高達91.4%的比例採用Linux為它們的作業系統。一些為手機開發的作業系統，使用Linux內核的修改後的版本，其中包括谷歌Android、Firefox OS、HP WebOS和諾基亞Maemo。

#### 內核錯誤和oops

<image>

在Linux中，內核錯誤（Kernel panic）是指作業系統在監測到內核系統內部無法恢復的錯誤，相對於在使用者空間代碼類似的錯誤。作業系統試圖讀寫無效或不允許的記憶體地址是導致內核錯誤的一個常見原因。內核錯誤也有可能在遇到硬體錯誤或作業系統BUG時發生。在許多情況中，作業系統可以在記憶體訪問違例發生時繼續運行。然而，系統處於不穩定狀態時，作業系統通常會停止工作以避免造成破壞安全和數據損壞的風險，並提供錯誤的診斷資訊。

在Linux上，oops即Linux內核的行為不正確，並產生了一份相關的錯誤日誌。許多類型的oops會導致內核錯誤，即令系統立即停止工作，但部分oops也允許繼續操作，作為與穩定性的妥協。這個概念只代表一個簡單的錯誤。當內核檢測到問題時，它會列印一個oops資訊然後殺死全部相關進程。oops資訊可以幫助Linux內核工程師調試，檢測oops出現的條件，並修復導致oops的程序錯誤。

### 安全

電腦安全是一個非常公眾化的主題，關係到Linux內核，因為大量在內核中的錯誤可能成為潛在的安全漏洞，是否允許提升權限漏洞或拒絕服務攻擊源漏洞。在過去的幾年中，許多這樣的缺陷被發現，並在Linux內核中被修補好。新的安全功能被繼續實現，以解決在Linux內核中的電腦不安全問題。

批評者指責內核開發人員，稱他們掩蓋（至少並未公佈）安全漏洞。2008年，作為回應，Torvalds稱：「個人認為，安全漏洞只是『正常的漏洞』。這些漏洞我並不去掩蓋，不過我不認為應當把它們特殊化，更不認為應該追蹤並公示它們......我不理會整個安全團隊，原因之一就是，我認為這些漏洞不僅美化還鼓勵了錯誤的行為。這令安全人員成了『英雄』，就猶如不修補正常漏洞的人就不值一提似的。而事實上，所有無聊的正常漏洞極為重要，僅僅因為它們實在太多了。我不認為該美化和關心那些嚴重的安全漏洞——它們並不及那些由死鎖造成的隨機嚴重崩潰來得更特殊。」

如2012年五月，SYSRET指令被發現在AMD和英特爾處理器間在實現方面有差異，這個差異在Windows、FreeBSD、XenServer和Solaris這些主流作業系統會導致漏洞。2012年六月，Linux核心中該問題已被修復。

2021年，來自明尼蘇達大學的研究人員，曾藉由貢獻修補程式至Linux核心的名義，利用修補程式導入Bug和漏洞，以觀察Linux核心社群的反應，再度故技重施時被發現，之後維護人員封鎖了所有來自該大學的貢獻，與移除過去該大學曾經貢獻的程式碼。

## 開發

### 開發者社區

截止2007年，內核開發已經從20位最活躍開發者寫80%的代碼轉變為頂端30人寫30%的代碼，而頂端開發者花費更多的時間審核變更。開發者還可以按從屬關係來歸類；在2007年，頂端類屬是「不知名」而頂端公司是Red Hat，它占有12%的貢獻，而知名業餘愛好者占3.9%。在2007年中所做內核變更已經由超過1900位開發者提交。一般假定Linux內核開發者社區由5000或6000名成員組成。

Linux基金會發表的 2016年Linux內核開發報告的更新表明，從版本3.18（2014年12月）至4.7（2016年7月）期間：平均每次發行有來自200-250個公司的大約1500位開發者作出貢獻。頂端30位開發者貢獻了稍大於16%的代碼。在公司中，頂端貢獻者是Intel（12.9%）和Red Hat（8.0%），第三和第四位為「none」（7.7%）和「unknown」（6.8%）類屬。

### 開發過程與模式

一個想要對 Linux 內核進行修改的開發者一般就從對那個修改的開發和測試開始著手。接下來的過程取決於變化的重要程度，及修改該變更的子系統數量是由單個還是多個修補程序組成。如果僅僅是修改了由單個維護人員維護的單個子系統，那麼這些修改的補丁代碼就直接通過Cc中某個郵件列表發送給相關的維護人員。郵件列表的閱讀者和子系統的維護人員將檢查補丁代碼並提供反饋。一旦審查過程完成，維護者接受他內核代碼樹中的補丁。如果這些更改被認為是夠重要的錯誤修復，那麼包含這些修補程序的拉取請求（pull request）將在幾天內發送給Linus。否則，將在下一個合併窗口時向Linus發送拉取請求。合併窗口通常會持續兩周，並在之前的內核版本發布後立即啟動。

Linus Torvalds擁有對Linux內核能夠接受哪些更改和誰可以成為維護者的最終決定權。內核維護者在他們自願放棄之前將維持他們的角色。目前，沒有任何已知的內核維護者被要求退出。此外，還沒有一個內核維護者因與其他維護者的交互風格的因素而受到Linus批評的例子。這為維護者提供了寬鬆的社區空間。雖然內核開發社區的文化多年來有所改善，但曾有一段時間它的聲譽很糟糕。認為自己遭受了不公正對待的開發者可以向Linux基金會的技術專家委員會報告。儘管如此，一些社區成員仍然不認同現在的討論氛圍。

#### 同 Linux 發行版的關係

大多數Linux使用者運行一個由他們 Linux 發行版提供的內核。一些發行版搭載的是 Linux 的通用內核（也就是 「vanilla」或「stable」）版本。不過，一些Linux內核發行商（如Red Hat和SUSE）會維護他們自己的內核分支。這些發行商分支的內核版本通常相對於穩定版本（vanilla）而言更新的速度更慢一些，但是同樣會包括所有相關的穩定版本分支的補丁。此外，他們同時也會增添一些新特性和對新硬體的支持，而這些支持是這些發行商分支基於的穩定分支所不包括的。

### 主線Linux

包含Linux內核的Linus Torvalds的Git樹被稱為主線Linux。每個穩定的內核發布都源自主線樹，並經常在kernel.org上發布。主線Linux只對運行Linux的眾多設備中的一小部分設備提供堅實的支持。非主線支持由獨立項目（如Yocto或Linaro）提供，但在許多情況下需要設備供應商的內核。使用供應商內核可能需要一個板級支持包。

在主線Linux之外維護一個內核樹已被證明是困難的。

主線化（Mainlining）是指將對設備的支持添加到主線內核中的努力，而以前只有在分支中支持或根本沒有支持。這通常包括添加驅動程序或設備樹文件。完成後，該功能或安全修復被視為mainlined。

### 重新開發的估價

<image>

按照傳統商業軟體開發的方式，重新開發Linux 2.6.0內核的估計代價將是6.12億美元（4.67億歐元、3.94億英鎊），以2004年的COCOMO人月估計模型.在2006年，歐盟資助的一項研究表明，重新開發Linux 2.6.8以後的內核，代價是8.82億歐元（11.4億美元、7.44億英鎊）。

截至2011年1月4日，使用當前的代碼行（LOC）和大衛·惠勒的計算工資數，這將花費約30億美元（約22億歐元），才能夠重新開發Linux的內核。

### 版本命名

Linux內核有三個不同的命名方案。早期版本：第一個版本的內核是0.01，其次是0.02,0.03,0.10,0.11,0.12（第一GPL版本),0.95,0.96,0.97,0.98,0.99及1.0。從0.95版有許多的補丁發布於主要版本版本之間。

舊計劃（1.0和2.6版之間)，版本的格式為A.B.C，其中A,B,C代表：A大幅度轉變的內核，這是很少發生變化，只有當發生重大變化的代碼和核心發生才會發生，在歷史上曾改變兩次的內核：1994年的1.0及1996年的2.0； B是指一些重大修改的內核，內核使用了傳統的奇數次要版本號碼的軟體號碼系統（用偶數的次要版本號碼來表示穩定版本）；C是指輕微修訂的內核，這個數字當有安全補丁，bug修復，新的功能或驅動程序，內核便會有變化。自2.6.0（2003年12月）發布後，人們認識到，更短的發布周期將是有益的。自那時起，版本的格式為A.B.C.D，其中A,B,C,D代表：A和B是無關緊要的，C是內核的版本，D是安全補丁。

自3.0（2011年7月）發布後，版本的格式為3.A.B，其中A,B代表：A是內核的版本，B是安全補丁。而4.0（2015年4月）釋出後，則延續3.A.B的命名格式，只是將主版號變更為4。

## 法律層面

### 許可證

原先托瓦茲將 Linux 置於一個禁止任何商業行為的條例之下，但0.12版本之後改用 GNU 通用公共許可證第二版。該協議允許任何人對軟體進行修改或發行，包括商業行為，只要其遵守該協議，所有基於Linux的軟體也必須以該協議的形式發表，並提供原始碼。

托瓦茲曾經公開聲稱將Linux置於GNU通用公共許可證之下是他一生中所做的「最好的決定」。

#### GPL第三版

Linux 內核明確地僅發表在 GNU 通用公共許可證（GPL）第二版下，而不向被許可方提供選擇「任何更高版本」的選項（這是常見的 GPL 擴展）。關於如何輕鬆地改變許可證以使用後來的 GPL 版本（包括第3版）以及這種更改是否合乎需要，存在著相當多的爭論。托瓦茲本人在版本2.4.0的發布中明確指出，他自己的代碼僅在版本2下發布。然而，GPL的條款規定，如果沒有指定版本，那麼可以使用任何版本；並且艾倫·考克斯指出，很少有其他 Linux 貢獻者指定了特定版本的 GPL。

2006年9月，對29位關鍵內核程式設計師的調查顯示其中的28位更傾向於使用 GPL 第二版（GPLv2）而非當時的 GPL 第三版（GPLv3）草案。托瓦茲評論說：「我認為一些外界人士......相信我才是那個古怪不合群的人，因為我這麼大張旗鼓地不做 GPLv3 的忠實粉絲。」這些高水平的內核開發者就大眾媒體對 GPLv3 的反對發表了評論，其中包括林納斯·托瓦茲本人、葛雷格·克羅哈曼和安德魯·莫頓。他們提到有關DRM/TiVo化、專利及「附加限制」的條款，並警告GPLv3對「開源宇宙」的巴爾幹化。決定不採用 GPLv3 作為 Linux 內核許可證的托瓦茲在幾年後重申了他的批評。

#### 韌體爭議

許可證爭議的一個重點是Linux使用韌體二進位包以支援某些硬體裝置。理察·馬修·斯托曼認為這些東西讓Linux某部份成為非自由軟體，甚至以此散佈Linux更會破壞GPL，因為GPL需要完全可獲取的原始碼。

林納斯·托瓦茲及Linux社群中的領導者，支持較寬鬆的許可證，不支持理察·馬修·斯托曼的立場。社群中的Linux-libre提供完整的自由軟體韌體。

#### 載入式核心模組許可證

另一個爭論點，就是載入式核心模組是否算是智慧財產權下的衍生創作，意即LKM是否也受GPL約束？托瓦茲本人相信LKM僅用一部分「公開」的核心介面，因此不算衍生創作，因此允許一些僅有二進位包裹的驅動程式或不以GPL宣告的驅動程式用於核心。但也不是每個人都如此同意，且托瓦茲也同意很多LKM的確是純粹的衍生創作，也寫下「基本上，核心模組是衍生創作」這樣的句子。另一方面托瓦茲也說過：

特別像繪圖卡驅動程式就有非常大的爭議，也許到最後得由立法機關給個答案。

### SCO爭議

在2003年3月，SCO Group對IBM提告，聲稱IBM將一些在SCO智慧財產權許可證保護下的Unix原始碼植入Linux中，破壞了SCO給予IBM的原始碼使用許可權。另外SCO也發出一大堆存證函給許多公司，警告他們在沒有SCO許可權的情況下使用了Linux，此舉可能導致侵犯智慧財產權，並且以起訴為手段對個別使用者施壓。SCO也同時對Novell、戴姆勒克萊斯勒（DaimlerChrysler，在2004年7月被部份駁回）以及AutoZone提出告訴，且被Red Hat與其他反對SCO論點的公司反告。2007年8月24日，聯邦法院審理SCO對Novell案（SCO v. Novell），法院認定Novell才是Unix商標的合法擁有者，而不是SCO。2010年3月20日，美國聯邦第十巡迴上訴法院宣判，Novell才是UNIX與UnixWare商標的合法擁有者。此項判決宣布後，已進入破產保護程序的SCO公司，決定停止繼續提出訴訟。

## 基本資料

- 軟體版本週期：Linux
- 域：Linux官方的吉祥物，一隻叫Tux的企鵝
- 開發者：林納斯·托瓦茲（Linus Torvalds）和幾千名合作者
- 作業系統家族：類Unix系統
- 發行日期：0.02 (1991年10月5日)
- 程式語言：C語言、Rust、彙編語言
- 語言：多語言
- 內核類別：單核心
- 軟體版本週期：7.1.7
- 軟體版本週期：7.1.7
- 許可證：GPL（僅）第二版、各類封閉固件的許可證
- 域：Linux的吉祥物Tux