---
# System prepended metadata

title: 第一講：作業系統術語及概念
tags: [Linux]

---

# 第一講：作業系統術語及概念

> 本筆記僅為個人紀錄，相關教材之 Copyright 為[jserv](http://wiki.csie.ncku.edu.tw/User/jserv)及其他相關作者所有
* 直播：==[Linux 核心設計：作業系統術語及概念 (2024-2-23)](https://youtu.be/8yd6p3GaxVs?si=_KsDdVXqDDl0iFjh)==
* 詳細共筆：[Linux 核心設計：作業系統術語及概念](https://hackmd.io/@sysprog/linux-concepts)
* 主要參考資料：
    * [Linux Kernel：Introduction](https://linux-kernel-labs.github.io/refs/heads/master/lectures/intro-slides.html)

---

## 引言

面對 Linux 核心 (2023 年) 超過 3 千 7 百萬行的龐大規模，學習者最感挫折之處，往往並非缺乏程式註解，而是即便註解詳盡，仍因對作業系統基礎認知的侷限而難以理解。

根據 `tokei` 工具統計，Linux 6.8.0-rc3 版本的原始碼總行數達到 3741 萬行，若扣除註解與空白行，仍有超過 2800 萬行，其中 C 語言佔約 2500 萬行。相較於 30 年前約 1 萬行的規模，成長幅度驚人。

學習 Linux 核心之所以困難，核心在於對其背後相關的術語及概念掌握不清。過去在資訊工程或電機工程學系的作業系統課程中，多半學習分類性的知識 (如 Windows、Linux、macOS 的比較)，較少深入探討 Linux 核心中「異中求同」的共通概念，以及如何將這些概念對應到可實作、可持續改進的程式碼。

此外，Linux 核心涉及大量背景知識，如作業系統、計算機組織、計算機結構、資料結構、演算法等基礎學科。即便理論、概念、實作皆有涉獵，面對如此龐大的程式碼 (如 3700 萬行)，仍充滿挑戰。

#### 示範：`cacheinfo` 結構

以 Linux 標頭檔 `include/linux/cacheinfo.h` 中的 `struct cacheinfo` 為例：
```c
/**
 * struct cacheinfo - represent a cache leaf node
 * @id：This cache's id. It is unique among caches with the same (type, level).
 * @type：type of the cache - data, inst or unified
 * @level：represents the hierarchy in the multi-level cache
 * @coherency_line_size：size of each cache line usually representing
 *	the minimum amount of data that gets transferred from memory
 * @number_of_sets：total number of sets, a set is a collection of cache
 *	lines sharing the same index
 * @ways_of_associativity：number of ways in which a particular memory
 *	block can be placed in the cache
 * @physical_line_partition：number of physical cache lines sharing the
 *	same cachetag
 * @size：Total size of the cache
 * @shared_cpu_map：logical cpumask representing all the cpus sharing
 *	this cache node
 * @attributes：bitfield representing various cache attributes
 * @fw_token：Unique value used to determine if different cacheinfo
 *	structures represent a single hardware cache instance.
 * @disable_sysfs：indicates whether this node is visible to the user via
 *	sysfs or not
 * @priv：pointer to any private data structure specific to particular
 *	cache design
 *
 * While @of_node, @disable_sysfs and @priv are used for internal book
 * keeping, the remaining members form the core properties of the cache
 */
struct cacheinfo {
    // ... 欄位定義 ...
};
```
這個結構體顯然與快取 (Cache) 有關，但其涉及的 `cache` 概念遠比基礎課程複雜。註解中提及 `cache`、多個 CPU 間的分享 (`shared_cpu_map`)，暗示了與 CPU Mask 的關聯。若直接閱讀核心程式碼，需同時理解計算機結構、快取原理、多 CPU 環境、以及描述 CPU Mask 的資料結構 (如 `bitmask`) 等多重議題。其內部實作 (如 `cache_policy` 的定義與操作) 與快取行為的實際關聯，以及與 ACPI (Advanced Configuration and Power Interface) 的關係，都可能讓初學者感到困惑。

#### 學習目標

本筆記將回顧若干關鍵的作業系統術語與概念，例如：
*   `userspace` vs. `kernel space`
*   `Monolithic kernel` vs. `Microkernel`
*   `Address space` 及其共享機制
*   `Execution context`
*   `Multi-tasking`
*   `Preemptive kernel`
*   `Symmetric MultiProcessing` (SMP)
*   `CPU Scalability`
*   `Copy-On-Write` (COW)
*   `lock`

探討過程中，不僅將術語對應到 Linux 核心，也會參照 Solaris、Microsoft Windows NT、Plan 9、CMU Mach 等經典作業系統進行解說，幫助建立清晰的概念框架，以應對 Linux 核心的複雜性。

---

## 藉由星之卡比解讀 Linux 核心發展

Linux 核心於 1991 年發布，隔年任天堂推出了廣受歡迎的遊戲角色「星之卡比」 (Kirby)。Kirby 的特色是能吸入敵人並獲得其能力。有趣的是，Linux 核心的發展歷程也展現了類似的「吸入」特性，不斷從其他作業系統借鑒並發揚光大其獨特功能。

Linux 核心的創始人 Linus Torvalds 並非孤軍奮戰，而是藉由網際網路的協作，打造了全球最成功的開放原始碼專案。其發展初期恰逢 AT&T 與孕育 BSD UNIX 的加州大學柏克萊分校之間發生版權訴訟，導致自由流通的 UNIX 仿製品出現空缺。在那個個人電腦 (PC) 物美價廉的年代，Linux 核心的出現完美填補了這個空缺。
> 延伸閱讀：[從 Revolution OS 看作業系統生態變化](https://hackmd.io/@sysprog/revolution-os-note)

Linux 核心「吸入」並整合其他作業系統概念的案例包括：

*   **虛擬記憶體管理 (Virtual Memory Management, MM)**：
    *   Linux 核心具備現代作業系統的 `page-based` MM 機制。
    *   此概念最初源於卡內基梅隆大學 (CMU) 在 1980 年代發展的 Mach `microkernel`。
    *   後被 BSD (Berkeley Software Distribution) 採納。
    *   Linux 核心在開發早期便參照 BSD 的設計，「吸入」了現代的虛擬記憶體管理機制。
*   **procfs (Process File System)**：
    *   UNIX 哲學中一個著名的特色是 "Everything is a file"。然而，這句話並不完全精準，傳統 UNIX 和 BSD 並未完全落實此理念 (例如 `socket` 就是例外)。
    *   貝爾實驗室 (Bell Labs) 在 UNIX 之後發展的 Plan 9 作業系統，才更徹底地實踐此理念，將所有裝置和服務都視為檔案進行操作 (如 `telnet`、`ftp`、`nfs` 等)。
    *   Linux 核心採納了 Plan 9 的設計思想，將 `process` (行程) 的內部資訊以檔案系統 (`/proc`) 的形式呈現。
*   **TCP/IP stack**：
    *   BSD 是 TCP/IP 開發的重要基地，也是推動電腦網路技術普及的關鍵作業系統。
    *   Linux 核心早期就「吸入」了 BSD 的 TCP/IP `protocol stack`。
    *   搭上網際網路發展的熱潮，成為奠定今日網路服務基礎的關鍵。
*   **BPF (Berkeley Packet Filter) -> [eBPF](https://hackmd.io/@Jaychao2099/Linux-kernel-4) (Extended BPF)**：
    *   BPF 最初的動機是作為封包過濾機制 (例如用於防禦 DDoS 攻擊)。
    *   被 Linux 核心「吸入」並擴充為 `eBPF` 後，演變成強大的核心內建行為分析工具。
    *   可用於動態/靜態追蹤 (dynamic/static tracing) 和效能分析 (profiling events)，成為 Linux 核心的獨特技術。
*   **9p (Plan 9 Protocol)**：
    *   Plan 9 為了貫徹 "Everything is a file" 理念，引入 9P 通訊協定，用以統一存取遠端資源 (remote resources) 和本地檔案 (local file)，無需區分資源位置。
    *   這類似於 Linux 中的 VFS (Virtual File System) 抽象層概念。
    *   儘管 Plan 9 在商業上未獲成功，Linux 核心「吸入」9P 後，將其應用於虛擬化技術 (如 `host` 與 `guest` 之間的檔案共享)，創造了巨大的商業價值。
*   **lxc (Linux Containers)**：
    *   借鏡了 FreeBSD jail 和 Solaris container 的方案。
    *   利用 Linux 核心的 `namespace` 和 `cgroups` 等機制重新實現了容器化的概念。
*   **[mseal](https://docs.kernel.org/userspace-api/mseal.html) 系統呼叫**：
    *   始於 Linux v6.10 的近期案例。
    *   現代微處理器支援對記憶體的讀寫 (RW, Read-Write) 和不可執行 (NX, No-Execute) 位元進行管理，`mseal` 利用此特性提升記憶體損壞錯誤時的防禦能力。
    *   可以防止本應唯讀的記憶體 (如 `.text`, `.rodata` 區段) 被修改或重新映射，維持控制流完整性 (Control-Flow Integrity, CFI)。
    *   類似功能也存在於 macOS (XNU 核心的 `VM_FLAGS_PERMANENT` 旗標) 和 OpenBSD (`mimmutable` 系統呼叫)。

### 看漫畫學 Linux
Daniel Stori 的網站提供[一系列關於資訊技術的漫畫](https://hackmd.io/@sysprog/linux-comic)，可作為理解 Linux 核心機制與相關套件的輔助。

---

## 高階觀點

本節內容參考投影片：[Linux Kernel：Introduction](https://linux-kernel-labs.github.io/refs/heads/master/lectures/intro-slides.html) ([重點描述](https://linux-kernel-labs.github.io/refs/heads/master/lectures/intro.html))。

### User vs. Kernel (使用者 vs. 核心)

作業系統區分不同的執行模式 (Execution modes) 與記憶體空間，以確保系統穩定性與安全性。

*   **執行模式 (Execution Modes)**：
    *   **Kernel Mode (核心模式)**：處理器在此模式下擁有最高權限，可以執行所有指令，存取所有硬體資源。作業系統核心運行於此模式。
    *   **User Mode (使用者模式)**：處理器在此模式下權限受限，只能執行部分指令，對硬體資源的存取需透過系統呼叫 (System Call) 請求核心代理。應用程式運行於此模式。
*   **記憶體保護 (Memory Protection)**：
    *   **Kernel Space (核心空間)**：存放作業系統核心程式碼與資料的記憶體區域，受到硬體保護，使用者模式程式無法直接存取。
    *   **User Space (使用者空間)**：存放應用程式程式碼與資料的記憶體區域，每個行程擁有獨立的 `user space`，彼此隔離。
![Windows User Mode 與 Kernel Mode 示意圖](https://hackmd.io/_uploads/HJycNKAca.png)
[來源](https://docs.microsoft.com/zh-tw/windows-hardware/drivers/gettingstarted/user-mode-and-kernel-mode)
*   **硬體抽象層 (Hardware Abstraction Layer, HAL)**：如上圖 Windows 範例所示，HAL 是一個軟體層，用於隱藏不同硬體平台之間的差異，使作業系統核心能夠在不同硬體上運行。Windows NT 設計之初就希望能在 x86、Alpha、MIPS 等不同架構上運行，HAL 扮演了關鍵角色。
*   **驅動程式位置**：
    *   大部分驅動程式運行在 `kernel space`。
    *   **特例 1 (Windows)**：輸入法編輯器 (Input Method Editor, IME) 在 Windows 中被實作為鍵盤驅動程式 (`Keyboard Driver`)，運行在 `kernel space`。若輸入法設計不良，可能導致整個 Windows 系統崩潰。
    *   **特例 2 (Linux/Unix)**：部分驅動程式可運行在 `user space`，例如 X Window System 的顯示驅動程式、NVIDIA 的專有驅動程式等。`user space` 驅動程式通常包含一個小的 `kernel space` 輔助模組 (shim/helper)，主體邏輯則在 `user space` 執行。這樣做的好處是彈性較大，且廠商無需以 GPL (GNU General Public License) 授權釋出其專有程式碼。
*   **歷史背景：分時多工 (Time-Sharing)**：
    *   1960 年代，電腦非常昂貴。Fernando J. Corbató 教授領導開發了世界上第一個分時多工作業系統 CTSS (Compatible Time-Sharing System)，允許多個使用者透過終端機 (如 Teletyper) 同時操作一台電腦，共享運算和儲存資源。
    *   CTSS 的成功啟發了後續的 MULTICS 和 UNIX 作業系統。
    *   當時作業系統核心的概念尚未成熟，常稱為 `Supervisory program`。
    *   `Teletyper` (電傳打字機) 是早期人機互動的主要方式，透過訊號線連接電腦，形成 `console` (主控台)。`tty` (Teletypewriter) 子系統的概念也從 UNIX 延續到 Linux。
    *   紀錄片：[1963 Timesharing：A Solution to Computer Bottleneck](https://youtu.be/Q07PhW5sCEk)

---

### Typical Operating System Architecture (典型作業系統架構)

一個典型的作業系統架構通常包含以下層次：
![image](https://hackmd.io/_uploads/HJi9SMPxxl.png)

*   **Hardware (硬體層)**：最底層的物理裝置。
*   **Kernel (核心層)**：
    *   **Device Drivers (裝置驅動程式)**：控制特定硬體裝置的軟體。
    *   **Kernel Core (核心主體)**：提供作業系統核心功能，如行程管理、記憶體管理、檔案系統等。運行在 `Kernel Mode`，佔據 `Kernel Space`。
*   **System Call Interface (系統呼叫介面)**：`User Space` 應用程式請求核心服務的唯一途徑，作為 `User Mode` 和 `Kernel Mode` 之間的橋樑。
*   **User Space (使用者空間)**：
    *   **Applications (應用程式)**：使用者執行的各種程式。運行在 `User Mode`。

---

### Fork/Join 並行處理模型

1963 年，電腦科學家 Melvin Conway 提出了 `fork` 的思想，作為一種「多處理器並行處理」的執行模型。

```graphviz
digraph Graph1
{
    graph [splines=ortho];
    node [style=rounded shape=box label=""];
    A;
    
    
    subgraph cluster_fork {
        style="rounded";
        label="             fork 點";
        B[style=diagonal shape=diamond];
    }
    
    subgraph cluster_join {
        style="rounded";
        label="                  join 點";
        D;
    }
    
    subgraph cluster_parallel1 {
        label="可並行         ";
        CL;
    }
    
    subgraph cluster_parallel2 {
        label="         可並行";
        CR;
    }
    E;
    
    
    A -> B;
    B -> {CL CR};
    {CL CR} -> D;
    D -> E;
}
```

*   **Fork**：流程圖中的分岔點，代表一個行程 (父行程) 可以分裂創建出一個或多個邏輯上獨立的新行程 (子行程)，這些子行程可以並行執行。
*   **Join**：多個並行執行的行程需要同步或會合的時間點。在現代多執行緒程式設計中，`pthread_join()` 或 `java.lang.Thread.join()` 等函式就體現了這個概念。
*   **並行 (Concurrency)**：指系統能夠處理多個任務的能力，這些任務可能交錯執行 (interleaving) 或同時執行 (simultaneously，在多核處理器上)。重點在於任務之間邏輯上的獨立性與推進。
    > [!Tip]注意：
    > "concurrent" (並行) 強調多個任務可以推進，但不一定同時發生。對比 "simultaneous" (同時)。

---

### process 與 processor 的抽象與排程器 (Scheduler)

Conway 的論文另一個創舉是將 **行程 (process)** (當時的概念，後來演變為作業系統中的 process) 與執行行程的 **處理器 (processor)** (CPU) 分離，抽象出 **排程器 (scheduler)** 的概念。

```graphviz
digraph Graph2 {
    graph [nodesep=2]
    node [shape=box];
    B [label="一堆處理器"];
    A [label="一堆行程"];
    
    B -> A [style=dotted dir=both label="    多對多映射"]; 
    
    A -> B [dir=both label="  scheduler"]
}
```

*   **抽象**：`scheduler` 將系統中所有的 `processor` (資源提供者) 和所有的 `process` (資源消費者) 視為統一的集合，進行管理和調度。
*   **映射**：建立 `process` 到 `processor` 的多對多映射關係 (雖然也可能特化為一對一或多對一)。這解釋了為何執行單元被稱為 `process`，而硬體單元稱為 `processor`，兩者並非巧合，而是刻意設計的函數關係。
*   **目標**：`scheduler` 的核心任務是在滿足系統約束 (如可用處理器數量) 的前提下，有效地將 `process` 分配給 `processor` 執行，並決定下一個要執行的任務。
*   **公平性 (Fairness)**：排程器需要確保所有等待執行的有效 `process` 都有機會被執行，避免某些 `process` 永久飢餓。

這個將 `process` 與 `processor` 分離並透過 `scheduler` 進行抽象映射的思想，深刻影響了後來的 UNIX 和 Linux。

*   **操作系統的幻覺 (Illusion)**：
如 [OSTEP (Operating Systems：Three Easy Pieces)](https://pages.cs.wisc.edu/~remzi/OSTEP/) 教科書所提，作業系統的核心功能之一是創造「幻覺」。
    *   **幻覺一：多個 CPU**：透過分時多工，在單一 CPU 上模擬出有許多 CPU 各自執行不同程式的假象。
    *   **幻覺二：巨大的私有記憶體**：透過虛擬記憶體，讓每個行程感覺自己獨佔了整個記憶體空間。

    理解作業系統如何創造和管理這些幻覺是掌握其核心概念的關鍵。

---

### Monolithic kernel vs. Microkernel (單體核心 vs. 微核心)

作業系統核心的架構主要有兩種風格：

*   **Monolithic kernel (單體核心)**：
    *   **定義**：作業系統的大部分功能 (行程管理、記憶體管理、檔案系統、裝置驅動程式、網路堆疊等) 都整合在一個單一、巨大的核心程式中，運行在 `kernel space`。
    *   **優點**：元件間的函數呼叫效率高，因為都在同一個位址空間。
    *   **缺點**：核心龐大複雜，開發、除錯、維護困難；一個元件 (如驅動程式) 的錯誤可能導致整個核心崩潰；擴充性較差。
    *   **例子**：傳統 UNIX、Linux (雖然具備模組化特性)。
![image](https://hackmd.io/_uploads/rJH2_fvxgx.png)
*   **Microkernel (微核心)**：
    *   **定義**：核心只包含最基本、最必要的功能，如行程間通訊 (IPC, Inter-Process Communication)、基礎排程、記憶體管理。其他作業系統服務 (檔案系統、網路堆疊、裝置驅動程式等) 則以獨立的伺服器行程 (server process) 形式運行在 `user space`。應用程式透過 IPC 與這些伺服器通訊來獲得服務。
    *   **優點**：核心精簡，可靠性高 (一個 `user space` 伺服器的崩潰通常不影響核心或其他伺服器) ；模組化程度高，易於擴充和替換元件；適合分散式系統。
    *   **缺點**：大量的 IPC 操作會帶來顯著的效能損耗，因為需要在 `user space` 和 `kernel space` 之間以及不同的 `user space` 行程之間切換和複製資料。
    *   **例子**：Mach、QNX、L4 Family、MINIX 3。
![image](https://hackmd.io/_uploads/HkXRdGvgxx.png)
*   **Mach 簡介**：
    *   由 CMU 於 1980 年代開發，目標是取代日益龐大的 UNIX 核心。
    *   設計目標包含 UNIX 相容、物件導向、跨平台、適合分散式運算。
    *   **核心元件**：`ports` (通訊埠), `messages` (訊息), `tasks` (資源容器，類似行程), `threads` (執行緒), `virtual memory`。`task` 是資源分配單位，`thread` 是執行單位。
    *   **主要開發者**：Richard Rashid、Avie Tevanian (後者曾在 NeXT 和 Apple 擔任要職)。
    *   **影響**：雖然 Mach 本身式微，但其許多技術 (如 `microkernel` 概念、IPC、執行緒、虛擬記憶體) 深刻影響了後續的 BSD、Linux、macOS、Windows NT 等作業系統。
*   **歷史爭論：Tanenbaum vs. Torvalds**：
    *   1992 年，MINIX 的作者 Andrew Tanenbaum 教授與 Linux 的作者 Linus Torvalds 在 `comp.os.minix` 新聞群組上展開了一場著名的辯論。
    *   Tanenbaum 認為 `monolithic kernel` 已經過時，`microkernel` 才是未來趨勢，批評 Linux 的設計。
    *   Torvalds 則為 `monolithic` 架構辯護，強調實用性與效能。
    *   **背景**：MINIX 是 Tanenbaum 為教學目的開發的 `microkernel` 作業系統，而 Linux 早期開發時使用了 MINIX 的檔案系統，並在其社群進行討論，某種程度上引發了 Tanenbaum 的不滿。
    *   **結果**：歷史證明，儘管 `microkernel` 在理論上更優雅，但 `monolithic kernel` (特別是模組化的 Linux) 在效能和生態系發展上取得了巨大成功。

*   **Microkernel 的挑戰與演進**：
    *   **效能問題**：早期的 `microkernel` (如 Mach 2.5/3.0) 因 IPC 成本過高而效能不彰。
    *   **第二代 Microkernel (L4)**：德國電腦科學家 Jochen Liedtke 重新設計並實作了 L4 `microkernel`，大幅優化 IPC 效能，證明了 `microkernel` 在效能上可以與 `monolithic kernel` 競爭。L4 家族被廣泛應用於嵌入式系統和行動裝置 (如高通處理器中)。
    *   **seL4**：由澳洲 NICTA (現 Data61) 開發，是 L4 的一個分支，以其形式化驗證 (formal verification) 著稱，是世界上第一個被完全驗證的通用作業系統核心，保證實作符合設計規範，具有極高的安全性與可靠性。

---

### Monolithic kernels can be modular (單體核心的模組化)

雖然 Linux 核心是 `monolithic` 架構，但它也具備高度的模組化特性：

*   **編譯時配置 (Compile-time configuration)**：核心的許多元件和功能可以在編譯時啟用或禁用。
*   **可載入核心模組 (Loadable Kernel Modules, LKMs)**：允許在**執行階段動態地載入和卸載核心元件** (如裝置驅動程式、檔案系統)。這使得核心可以在不重新編譯的情況下擴充功能，也讓第三方開發者更容易提供驅動程式。
*   **子系統 (Subsystems)**：核心被組織成邏輯上獨立的子系統 (如記憶體管理、排程器、網路、VFS 等)。
*   **嚴格的介面 (Strict interfaces)**：子系統之間透過定義良好的介面進行互動，但這些介面通常透過巨集 (macros) 、內聯函式 (inline functions) 、函式指標 (function pointers) 等方式實現，以降低效能損耗。

> 參見 [Linux 核心模組掛載機制](https://hackmd.io/@sysprog/linux-kernel-module)

---

### "Hybrid" kernels (混合核心)

有些作業系統被描述為 `Hybrid kernel`，試圖結合 `monolithic kernel` 的效能和 `microkernel` 的模組化/穩定性優點。

*   **Linus Torvalds 的觀點**：他認為 "Hybrid kernel" 更多是市場行銷術語，本質上仍是 `monolithic kernel`，只是借用了 `microkernel` 的一些概念來包裝。
*   **常見特徵**：通常有一個 `monolithic` 核心，但部分非關鍵服務 (可能包括某些驅動程式或檔案系統) 運行在 `user space`，或者核心內部結構借鑒了 `microkernel` 的設計 (如訊息傳遞)。
*   **例子**：
    *   **Microsoft Windows NT (及後續版本)**：最初設計受 Mach `microkernel` 影響，有一個小的執行體 (Executive) 和多個子系統 (如 Win32、POSIX)。但為了效能，許多圖形和視窗管理元件後來被移回 `kernel space`，使其更接近 `monolithic`。
    *   **Apple macOS/iOS (XNU Kernel)**：XNU 核心明確地結合了 Mach `microkernel` (提供 IPC、排程、VM 等基礎服務) 和 BSD UNIX 的元件 (提供 POSIX API、網路堆疊、VFS 等)，並加入了名為 I/O Kit 的物件導向驅動程式框架。它被認為是 `hybrid kernel` 的典型代表。
    *   **DragonFly BSD**：由 FreeBSD 的早期開發者 Matt Dillon 創建。它是一個 `monolithic kernel`，但其創新的 HAMMER 檔案系統的一部分邏輯實作在 `user space`，展現了混合設計的思路。

---

### 現代虛擬化與作業系統架構演進

隨著雲端運算和虛擬化技術的普及，作業系統架構出現了新的演化方向，旨在滿足特定場景 (如安全性、效能、資源利用率) 的需求：

*   **MicroVM**：
    *   **概念**：極度輕量化、客製化的虛擬機器 (VM)，移除了通用 VM 中非必要的元件 (如圖形介面、多數驅動程式)，只保留應用程式運行所需的最少資源 (如網路、儲存)。
    *   **優點**：啟動速度快 (毫秒級) 、資源佔用低 (MB 級記憶體) 、安全性高 (VM 級隔離)。
    *   **應用**：`Serverless` 運算、容器化工作負載的快速部署。
    *   **例子**：AWS Firecracker (用於 AWS Lambda, AWS Fargate)。
    *   **整合**：為了方便開發和部署，`MicroVM` 實作通常會內建容器管理介面，讓使用者可以像操作容器一樣部署應用。
*   **Unikernel**：
    *   **概念**：將應用程式與其**所需的最小化作業系統函式庫** (Library OS) **靜態編譯成一個單一、獨立、不可變的映像檔**，直接運行在硬體或 `hypervisor` 之上。
    *   **特性**：
        *   單一位址空間 (Single Address Space)。
        *   單一處理程序 (Single Process，通常無法 `fork`)。
        *   極小的攻擊面，安全性高。
        *   效能高，延遲低 (無 `user/kernel` 模式切換開銷)。
    *   **歷史**：Library OS 的概念可追溯到 1990 年代的研究 (如 MIT 的 Exokernel/Aegis)。
    *   **例子**：NanoVMs/nanos、MirageOS、IncludeOS。
    *   **應用**：特定功能伺服器 (如 Web server、DNS server) 、嵌入式系統、高效能運算。
*   **Container Sandbox**：
    *   **概念**：旨在提升傳統 Linux 容器 (如 Docker) 安全性的技術。透過引入一個**攔截層 (Kernel Proxy)**，在容器與主機核心之間建立隔離，使得每個容器 (或一組容器) 看似擁有自己的核心介面，而非直接共享主機核心。
    *   **目標**：在保持容器輕量、快速特性的同時，提供**接近 VM 的隔離性和安全性**。
    *   **實作**：Kernel Proxy 重新實作了容器所需的系統呼叫子集。
    *   **例子**：Google gVisor (使用 Go 語言實作系統呼叫)、Kata Containers (使用輕量級 VM 作為隔離邊界)。
    *   **權衡**：相較於純容器，會引入一定的效能開銷，但安全性顯著提升。

> 延伸閱讀：[Unikernel and immutable infrastructures](https://github.com/cetic/unikernels)

---

### Address space (位址空間)

位址空間是作業系統管理記憶體的基礎概念。

*   **Physical Address Space (實體位址空間)**：指實際硬體記憶體 (RAM) 和週邊裝置 (如顯示卡記憶體) 所使用的位址範圍。處理器可以直接存取。
*   **Virtual Address Space (虛擬位址空間)**：作業系統為每個行程提供的一個獨立、連續的位址空間。處理器在保護模式 (Protected Mode) 或分頁模式 (Paging Mode) 下看到的是虛擬位址。作業系統和 MMU (Memory Management Unit) 負責將虛擬位址映射到實體位址。
*   **Process Address Space (行程位址空間)**：每個行程看到的虛擬位址空間，通常包含程式碼區 (text) 、資料區 (data) 、堆疊區 (stack) 、堆積區 (heap) 等。
*   **Kernel Address Space (核心位址空間)**：作業系統核心使用的虛擬位址空間部分，通常位於每個行程虛擬位址空間的高位址部分，並在所有行程間共享 (但內容受保護)。

#### User and Kernel Sharing Virtual Address Space (使用者與核心共享虛擬位址空間)
![image](https://hackmd.io/_uploads/S1biczDggx.png)

*   在典型的 32 位元系統上，4GB 的虛擬位址空間通常被劃分為：
    *   較低位址區域 (如 0x00000000 - 0xBFFFFFFF，3GB)：`User Space`，每個行程私有。
    *   較高位址區域 (如 0xC0000000 - 0xFFFFFFFF，1GB)：`Kernel Space`，所有行程共享 (映射到相同的實體記憶體)，但只有在 `Kernel Mode` 下才能存取。
*   這種設計允許在進行系統呼叫或中斷處理時，無需切換整個位址空間映射，只需改變處理器權限模式即可存取核心資料，提高了效率。

#### 行程與執行緒的位址空間關係

![行程、使用者執行緒、核心執行緒的位址空間示意圖](https://hackmd.io/_uploads/SkroNt0c6.png)

*   **Processes only**：傳統模型，每個行程擁有獨立的位址空間。
*   **User thread (使用者執行緒)**：
    *   多個執行緒存在於單一行程的 `user space` 中，共享該行程的位址空間。
    *   執行緒的**創建、排程、同步完全在 `user space` 由函式庫管理** (例如 Green Threads)。
    *   核心對這些執行緒無感知。
    *   **優點**：執行緒切換快 (無需進入核心)。
    *   **缺點**：一個執行緒阻塞 (如等待 I/O) 會導致整個行程阻塞；無法利用多核處理器。
*   **Kernel thread (核心執行緒)**：
    *   **核心直接管理執行緒**，每個 `user space` 執行緒對應一個 `kernel space` 的執行緒實體。
    *   執行緒的創建、排程、同步由核心負責。
    *   **優點**：一個執行緒阻塞不影響其他執行緒；可以充分利用多核處理器。
    *   **缺點**：執行緒創建和切換開銷較大 (需要進入核心)。
    *   **Linux 的模型**：Linux 早期 `thread` 實作較為特殊，process 和 `thread` 界線模糊 (使用 `clone()` 系統呼叫創建，可以選擇性共享資源)。後來引入 NPTL (Native POSIX Thread Library)，提供了更符合 POSIX 標準的 1:1 模型 (一個 user thread 對應一個 kernel thread)，由核心進行排程。儘管如此，核心內部仍常將 `process` 和 `thread` 統稱為 `task`。

> 參照：
> * [第六講：不僅是個執行單元的 Process](https://hackmd.io/@Jaychao2099/Linux-kernel-6)
> * [第八講：記憶體管理](https://hackmd.io/@Jaychao2099/Linux-kernel-8)

---

### Execution contexts (執行情境)

程式碼在執行時**所處的狀態或環境**。Linux 核心主要區分兩種執行情境：

*   **Process Context (行程情境)**：
    *   代表核心**正在代表某個特定行程執行程式碼**。
    *   **來源**：
        *   **執行系統呼叫**：行程從 `User Mode` 切換到 `Kernel Mode` 來執行核心提供的服務。
        *   **處理異常 (Exception)**：如 Page Fault、除以零錯誤等，核心需要介入處理。
    *   **特性**：
        *   可以存取當前行程的資源 (如位址空間、檔案描述符)。
        *   可以睡眠 (Block)，例如等待 I/O 完成或等待鎖。核心排程器可以將 CPU 分配給其他行程。
*   **Interrupt Context (中斷情境)** (也稱為 Atomic Context):
    *   代表核心**正在處理一個硬體中斷**。
    *   **來源**：**硬體**裝置 (如網路卡、磁碟控制器、計時器) 發出中斷訊號，打斷當前正在執行的程式碼 (無論是 `User Mode` 還是 `Kernel Mode`)。
    *   **特性**：
        *   與特定行程無關，可能打斷任何行程。
        *   **不能睡眠**：中斷處理程式必須盡快完成，不能進行任何可能導致阻塞的操作 (如請求記憶體分配、獲取某些類型的鎖)。因為中斷可能發生在任何時候，如果中斷處理程式睡眠，可能導致系統死鎖或錯過更重要的中斷。
        *   執行的程式碼受到嚴格限制。
        *   總是運行在 `Kernel Mode`。
*   **中斷處理流程**：
    1.  硬體產生中斷 (`generates an interrupt`)。
    2.  中斷控制器 (`interrupt controller`) 通知處理器。
    3.  處理器 (`processor`) 打斷當前執行，保存現場。
    4.  跳轉到預設的中斷入口點 (`<entry.S>`)，執行架構相關的組合語言程式碼。
    5.  執行架構相關的 C 函式 (`Architecture-dependent C function`)，如 `do_IRQ()`。
    6.  查詢是否有對應的中斷處理程式 (`Is there an interrupt handler on this line?`)。
    7.  若有，執行所有註冊的處理程式 (`run all interrupt handlers`)，通常分為上半部 (Top Half，快速完成、屏蔽中斷) 和下半部 (Bottom Half，延後處理、允許中斷)。
    8.  處理完成後，執行 `ret_from_intr()`，恢復現場，返回被打斷的程式碼繼續執行。
![中斷處理流程示意圖](https://hackmd.io/_uploads/Hk524FAc6.png)
> 參照：[Linux 核心設計：中斷處理和現代架構考量](https://hackmd.io/@sysprog/linux-interrupt)

---

### Multi-tasking (多工)

指作業系統支援「同時」執行多個行程 (或任務) 的能力。實際上在單核 CPU 上是透過快速切換 (Context Switching) 在不同行程之間共享 CPU 時間來達成，給使用者一種多個程式同時運行的感覺。

*   **實作方式**：
    *   **Cooperative Multi-tasking (合作式多工)**：
        *   行程必須主動放棄 CPU 控制權 (yield)，其他行程才有機會執行。
        *   **優點**：實作簡單。
        *   **缺點**：如果一個行程不合作 (例如陷入無限迴圈或長時間不放棄 CPU)，會導致整個系統沒有回應。
        *   **例子**：早期 Windows (Windows 3.1 之前)、早期 macOS (Mac OS 9 之前)。
    *   **Preemptive Multi-tasking (搶佔式多工)**：
        *   作業系統核心 (排程器) 強制性地剝奪行程的 CPU 控制權，並將其分配給其他行程。通常基於時間片 (Time Slice) 或優先權 (Priority)。
        *   **優點**：系統回應性更好，單一行程無法獨佔 CPU。
        *   **缺點**：實作較複雜，需要處理行程切換和同步問題。
        *   **例子**：現代主流作業系統，包括 Linux、Windows NT 及後續版本、macOS X 及後續版本、UNIX 家族。
*   **Linux 的多工**：Linux 採用搶佔式多工。

> 參照：[第七講：不只挑選任務的排程器](https://hackmd.io/@Jaychao2099/Linux-kernel-7)
> 延伸閱讀：[並行和多執行緒程式設計](https://hackmd.io/@sysprog/concurrency)

---

### Preemptive kernel (搶佔式核心)

`Preemptive multitasking` 和 `Preemptive kernel` 是不同的概念。

*   **Preemptive Multitasking**：指作業系統**能夠搶佔使用者空間的行程**。
*   **Preemptive Kernel**：指 **核心本身也可以被搶佔**。也就是說，當一個行程正在執行核心程式碼時 (例如在系統呼叫中)，如果有一個更高優先權的行程準備就緒，核心可以中斷當前的核心執行，切換到更高優先權的行程。
*   **Non-preemptive kernel**：行程一旦進入核心模式，必須執行完畢或主動放棄 CPU (例如等待 I/O)，才能被其他行程取代。核心程式碼執行期間不會被搶佔。
*   **Linux 的核心搶佔**：
    *   早期 Linux 核心是非搶佔式的。
    *   後來引入了核心搶佔機制 (可透過編譯選項配置)：
        *   **`CONFIG_PREEMPT_NONE`**：傳統的**非搶佔式核心**。![image](https://hackmd.io/_uploads/rJ-KTfPxll.png)
        *   **`CONFIG_PREEMPT`**：在核心程式碼中插入顯式的**檢查點**，允許在這些點**進行自願搶佔**。![image](https://hackmd.io/_uploads/H1FjTGDege.png)
        *   **`CONFIG_PREEMPT_RT_BASE` (Real-Time)**：**完全搶佔式核心** (或稱硬即時核心)，旨在將核心中不可搶佔的部分減至最少，以提供更低的、可預測的延遲。修改了 `spinlock` 等同步機制，使其在大部分情況下可被搶佔。![image](https://hackmd.io/_uploads/rJypTMvlgl.png)
*   **核心搶佔點 (Preemption Points)**：在 `CONFIG_PREEMPT` 核心中，搶佔可能發生在：
    *   從中斷處理程式返回到可搶佔的核心程式碼時。
    *   核心程式碼明確檢查是否需要重新排程時 (`cond_resched()`)。
    *   核心程式碼解鎖了某個同步原語後。
*   **`preempt_count`**：每個行程的 `thread_info` 結構中有一個計數器，用於追蹤當前是否允許搶佔。當 `preempt_count` 為 0 時，才允許搶佔。進入不可搶佔區域 (如持有 `spinlock`) 時會增加計數，離開時減少計數。
*   **Fully Preemptive (`CONFIG_PREEMPT_RT_BASE`)**：
    *   **目標**：讓核心「幾乎」無處不可搶佔 ("Preempt Everywhere except...")。
    *   **例外情況**：當中斷被禁用 (`Interrupt disable`) 或搶佔被顯式禁用 (`Preempt disable`) 時。
    *   將 `spinlock` 替換為可睡眠的 `mutex` 或 `rtmutex`，將中斷處理的耗時部分移到執行緒上下文執行。
*   **搶佔的優缺點**：
    *   **優點**：提高系統回應速度，降低高優先權任務的延遲。對互動式應用和即時系統至關重要。
    *   **缺點**：增加核心的複雜性 (需要處理重入和同步問題) ；可能降低整體吞吐量 (`Throughput`)，因為行程切換本身有開銷。

> 參照：
> * [Linux 核心設計：PREEMPT_RT 作為邁向硬即時作業系統的機制](https://hackmd.io/@sysprog/preempt-rt)
> * [Linux 核心搶佔](https://hackmd.io/@sysprog/linux-preempt)

---

### Pageable kernel memory (可分頁核心記憶體)

指**核心的部分記憶體** (如部分程式碼、資料、核心堆疊或動態分配的記憶體) 可以像使用者空間記憶體一樣**被交換 (Swap) 到磁碟上**。

*   **優點**：可以在實體記憶體不足時，釋放出部分核心佔用的記憶體。
*   **缺點**：存取被換出的核心記憶體時需要將其換回，會增加延遲。核心的關鍵部分通常不可分頁。
*   **Linux**：Linux 核心的大部分記憶體是不可分頁的 (pinned in memory)，但某些部分 (如模組) 在特定情況下可能涉及分頁。

---

### Kernel stack (核心堆疊)

每個行程都有一個獨立的核心堆疊。當行程因系統呼叫或中斷進入核心模式時，核心會使用該行程的核心堆疊來**保存函數呼叫鏈、局部變數等狀態**。

*   **大小**：核心堆疊的大小通常很小 (如 4KB 或 8KB，依架構而定)。
*   **限制**：核心開發者必須避免在核心堆疊上分配大型資料結構，也要避免過深的遞迴呼叫，以防堆疊溢位 (Stack Overflow)，導致核心崩潰。

---

### Portability (可移植性)

指作業系統能夠在不同硬體架構 (如 x86, ARM, PowerPC, RISC-V) 上運行的能力。Linux 核心透過以下方式實現高度可移植性：

*   **架構特定程式碼 (Architecture specific code)**：存放於 `arch/` 目錄下，包含針對特定 CPU 架構和機器平台的組合語言和 C 程式碼。處理與硬體直接相關的操作，如啟動載入器介面、中斷控制器、記憶體管理單元 (MMU) 、SMP 控制器、匯流排控制器、異常處理、虛擬記憶體處理等。也包含針對特定架構優化的函式 (如 `memcpy`, `string` 操作)。
*   **架構無關程式碼 (Independent architecture code)**：核心的大部分程式碼是用 C 語言編寫的，與具體硬體架構無關。包含：
    *   **Kernel core**：進一步劃分為多個子系統 (排程、記憶體管理、IPC、VFS 等)。
    *   **Device drivers**：大部分裝置驅動程式也是架構無關的，透過標準介面與核心互動。

---

### Asymmetric MultiProcessing (ASMP) vs. Symmetric MultiProcessing (SMP) (非對稱多處理 vs. 對稱多處理)

描述多處理器系統中核心與處理器關係的兩種模式：

*   **ASMP (非對稱多處理)**：
    *   處理器之間的角色不對等。通常**有一個主處理器 (Master)** 運行作業系統核心，其他從處理器 (Slaves) 只執行使用者程式或特定任務。
    *   **優點**：核心實作相對簡單，因為不需要處理複雜的核心同步問題。
    *   **缺點**：主處理器容易成為瓶頸，系統擴展性受限。
![image](https://hackmd.io/_uploads/H1-6JXDgge.png)
*   **SMP (對稱多處理)**：
    *   **所有處理器地位對等**，都可以執行核心程式碼和使用者程式碼。作業系統核心和應用程式可以在任何可用的處理器上運行。
    *   **優點**：負載平衡更好，系統擴展性 (Scalability) 更佳。
    *   **缺點**：核心實作複雜，需要處理多個處理器同時存取共享資料的同步問題 (如使用 `spinlock`、`mutex` 等)。
    *   **Linux**：Linux 主要設計為 SMP 系統。
![image](https://hackmd.io/_uploads/ry8R1Xweee.png)
> 參照：[Linux 核心設計：多核處理器和 spinlock](https://hackmd.io/@sysprog/multicore-locks)

---

### CPU Scalability (CPU 可擴展性)

指系統效能如何隨著處理器核心數量的增加而成比例提升。理想情況下，核心數加倍，效能也應接近加倍 (線性擴展)。
![image](https://hackmd.io/_uploads/BJoGrEwggx.png)

*   **挑戰**：
    *   **鎖競爭 (Lock Contention)**：在 SMP 系統中，多個核心需要頻繁存取共享資料，保護這些資料的鎖 (如 `spinlock`) 會成為效能瓶頸。當核心數增加時，對鎖的競爭加劇，導致處理器花費大量時間等待鎖釋放，而非執行實際工作。
    *   **快取一致性 (Cache Coherence)**：多個核心各自擁有快取，維護不同核心快取中共享資料一致性的硬體協議 (如 MESI) 會帶來額外開銷。當一個核心修改資料時，需要使其他核心的快取副本失效或更新，這在高頻繁共享寫入的場景下成本很高。
    *   **演算法複雜度**：某些核心演算法本身可能不是 $O(1)$ 或 $O(log N)$ 的，隨著核心數 N 的增加，演算法**開銷可能不成比例地增長**。
*   **提升 Scalability 的方法**：
    *   **無鎖演算法 (Lock-free algorithms)**：使用原子操作 (Atomic Operations) 等技術避免使用傳統鎖，減少競爭。
    *   **細粒度鎖定 (Fine-grained locking)**：將一個大鎖拆分成多個小鎖，每個鎖保護更小的資料範圍，減少不同核心同時競爭同一個鎖的可能性。
    *   **讀寫鎖 (Read-copy update, RCU)**：一種針對讀多寫少場景優化的同步機制，允許讀取操作並行執行，無需加鎖，寫入操作則相對複雜但不會阻塞讀取者。
    *   **Per-CPU 資料**：為每個 CPU 核心維護一份獨立的資料副本，避免共享和鎖競爭。
    *   **關注演算法複雜度**：設計和選擇具有良好擴展性的核心演算法。
*   **負擴展性 (Negative Scalability)**：在某些情況下，增加更多核心反而可能導致效能下降，通常是因為鎖競爭或快取一致性開銷過於嚴重。這是 Linux 核心開發在過去 20 年中持續努力解決的關鍵問題。
![image](https://hackmd.io/_uploads/SkABr4vxee.png)

> 參照：[Linux 核心設計：Scalability 議題](https://hackmd.io/@sysprog/linux-scalability)
<!-- > [第十六講：Scalability 議題](https://hackmd.io/@Jaychao2099/Linux-kernel-16) -->
> 延伸閱讀：
> * [第十三講：淺談同步機制](https://hackmd.io/@Jaychao2099/Linux-kernel-13)
> * [第十五講：RCU 同步機制](https://hackmd.io/@Jaychao2099/Linux-kernel-15)
> * [從 CPU cache coherence 談 Linux spinlock 可擴展能力議題](https://hackmd.io/@sysprog/linux-spinlock-scalability)

---

### Virtual File System (VFS) (虛擬檔案系統)

VFS 是 Linux 核心中的一個抽象層，旨在提供一個統一的介面來處理各種不同的檔案系統 (如 ext4, XFS, Btrfs, NFS, procfs 等)。

*   **目標**：讓使用者空間應用程式和核心的其他部分可以用一致的方式 (如 `open()`, `read()`, `write()`, `close()` 等系統呼叫) 來操作檔案，而無需關心底層檔案系統的具體類型和實作細節。
*   **核心元件**：
    *   **`inode` (Index Node)**：代表一個檔案或目錄的元資料 (metadata)，如檔案類型、權限、大小、時間戳、資料區塊位置等。每個檔案系統有自己的 `inode` 實作。VFS 提供通用的 `struct inode`。
    *   **`dentry` (Directory Entry)**：代表一個目錄項，用於將檔名路徑解析為 `inode`。核心維護 `dentry` 快取以加速路徑查找。
    *   **`file` (File Object)**：代表一個打開的檔案實例，包含檔案指標 (當前讀寫位置) 、打開模式 (讀/寫) 等資訊。
    *   **`superblock`**：代表一個已掛載的檔案系統實例，包含該檔案系統的整體資訊。
*   **運作方式**：當應用程式操作檔案時，VFS 層接收請求，透過通用的資料結構和操作函數指標，將請求轉發給底層具體檔案系統的實作來完成。它也維護各種快取 (如 `dentry` 快取、`inode` 快取、頁面快取 `page cache`) 來提高效能。
![image](https://hackmd.io/_uploads/SJ0eIEvlxx.png)

> 參照：
> * [第九講：檔案系統概念及實作手法](https://hackmd.io/@Jaychao2099/Linux-kernel-9)
> * [Linux 核心設計：檔案系統概念及實作手法](https://hackmd.io/@sysprog/linux-file-system) - jserv

---

## 細部切入點

若想深入了解電腦執行程式的底層細節，可以閱讀 [cpu.land](https://cpu.land/) 網站的系列文章：

1.  **a rabbit hole into how your computer runs programs**：從程式如何被 CPU 執行的角度切入。
2.  **Slice Dat Time**：探討時間與排程。
3.  **How to Run a Program**：解釋程式載入與執行的過程。
4.  **Becoming an Elf-Lord**：深入 ELF (Executable and Linkable Format) 執行檔格式。
5.  **The Translator in Your Computer**：講解編譯器與組譯器的角色。
6.  **Let's Talk About Forks and Cows**：剖析 `fork()` 系統呼叫與 Copy-on-Write (COW) 機制。

此外，可參考澳洲新南威爾斯大學 (UNSW) 的進階作業系統課程教材：
*   課程名稱：[Advanced Operating Systems (COMP9242)](https://www.cse.unsw.edu.au/~cs9242/23/lectures.shtml) (2023)
*   相關投影片：[Unix and Linux Internals](https://www.cse.unsw.edu.au/~cs9242/23/lectures/08a-linux.pdf)
*   UNSW 的 seL4 團隊開發了全球首個經過形式化驗證的作業系統核心 seL4，其教材內容紮實且具備實務基礎。
*   **重點內容**：
    *   process model (行程模型)
    *   File system model (檔案系統模型)
    *   IPC (行程間通訊)
    *   Paged virtual memory (分頁虛擬記憶體)
    *   TCP/IP Networking (網路)
    *   Multiprocessing (多處理)

---

## 結論

學習 Linux 核心，目標並非看懂 3700 萬行的每一行程式碼，而是要掌握那些歷久彌新 (歷經時間考驗仍具價值) 的核心概念與設計原則。理解這些概念的歷史傳承 (如從 UNIX 到 Linux 的演變) 以及它們如何在 Linux 核心中落實至關重要。同時，也需關注核心開發者持續投入的方向，如 `Scalability`、`Concurrency`、`real-time` 特性，以及如何不斷擴充 "Everything is a file" 等核心理念。最終，理論學習仍需回歸程式碼的實踐與驗證。

---

:::spoiler 補充資料
## Linux 核心架構與關鍵子系統

### Linux source code layout (原始碼佈局)

Linux 核心原始碼頂層目錄結構清晰，主要目錄包括：
*   `arch`：架構特定程式碼。
*   `block`：區塊裝置層。
*   `certs`：憑證與簽名相關。
*   `crypto`：加密 API。
*   `Documentation`：文件。
*   `drivers`：裝置驅動程式。
*   `firmware`：韌體檔案。
*   `fs`：檔案系統 (包含 VFS)。
*   `include`：核心標頭檔。
*   `init`：核心初始化。
*   `ipc`：行程間通訊。
*   `kernel`：核心主體 (排程、同步等)。
*   `lib`：通用函式庫。
*   `mm`：記憶體管理。
*   `net`：網路堆疊。
*   `samples`：範例程式碼。
*   `scripts`：建構與輔助腳本。
*   `security`：安全性模組 (LSM)。
*   `sound`：音效子系統。
*   `tools`：核心開發與監控工具。
*   `usr`：早期使用者空間程式 (現主要用於 `initramfs`)。
*   `virt`：虛擬化相關。
![image](https://hackmd.io/_uploads/r18suNPxxg.png)

### Linux kernel architecture (核心架構)

核心內部由多個相互關聯的子系統構成，提供完整的作業系統功能：
*   **核心主體 (Kernel Core)**:
    *   Process Management (行程管理)
    *   Memory Management (記憶體管理)
    *   Inter-Process Communication (IPC, 行程間通訊)
    *   Security (安全性)
    *   Networking (網路)
    *   Virtual File System (VFS, 虛擬檔案系統)
    *   其他...
*   **裝置驅動程式 (Device Drivers)**:
    *   依照裝置類型分類 (如 `char`, `block`, `net`, `input`, `usb`, `drm` 等)。
    *   透過標準框架與核心互動。
*   **架構特定層 (Architecture Specific)**:
    *   處理與特定硬體架構相關的細節。
![image](https://hackmd.io/_uploads/BJs0_Nwllx.png)

### `arch` (架構特定程式碼)

`arch/` 目錄包含：
*   針對特定 CPU 架構 (如 x86, ARM, RISC-V) 的 **C** 和**組合語言**程式碼。
*   啟動**載入器介面**、**初始化**程式碼。
*   **處理硬體細節**：中斷控制器、SMP 控制器、匯流排控制器、異常與中斷設置、虛擬記憶體處理 (MMU 相關)。
*   **架構優化**的函式 (如 `memcpy`)。

### Device drivers (裝置驅動程式)

核心驅動程式的特點：
*   採用**統一裝置模型 (Unified device model)**。
*   各子系統 (如網路、區塊裝置) 有其**特定的驅動程式介面**。
*   支援多種驅動程式類型 (TTY, serial, SCSI, filesystem, ethernet, USB, framebuffer, input, sound 等)。

### Process management (行程管理)

負責行程與執行緒的生命週期管理：
*   提供基礎的 UNIX 行程管理 (如 `fork`, `exec`) 和 POSIX threads 支援。
*   將行程和執行緒抽象為 `task`。
*   實現作業系統層級虛擬化 (OS-level virtualization) 的基礎：
    *   **Namespaces (命名空間)**：**隔離**行程的資源視圖。
    *   **Control groups (cgroups)**：**限制**與**核算**行程使用的資源。

### Memory management (記憶體管理)

管理系統的記憶體資源：
*   **實體記憶體管理**：分配與釋放實體記憶體頁框。
*   **虛擬記憶體管理**：處理分頁 (paging)、交換 (swapping)、請求分頁 (demand paging)、寫入時複製 (Copy-on-Write, COW)。
*   **使用者空間服務**：管理行程的位址空間 (`mmap()`, `brk()`, shared memory)。
*   **核心內部服務**：提供記憶體分配器 (如 SLAB/SLUB/SLOB Allocators, `vmalloc`)。

### Block I/O management (區塊 I/O 管理)

處理對區塊裝置（如硬碟、SSD）的讀寫請求，採用分層架構：
*   Virtual Filesystem Switch (VFS)
*   Device Mapper (用於 LVM, dm-crypt 等)
*   Generic Block Layer (通用區塊層)
*   I/O scheduler (I/O 排程器，如 CFQ, deadline, noop, mq-deadline)
*   Block device driver (區塊裝置驅動程式)
![image](https://hackmd.io/_uploads/HJr7K4vegl.png)

### Networking stack (網路堆疊)

實現網路通訊功能，同樣採用分層模型：
*   Berkeley Socket Interface (BSD Socket API)
*   Transport layer (傳輸層：TCP, UDP)
*   Network layer (網路層：IP, Routing, NetFilter/iptables)
*   Data link layer (資料鏈結層：Ethernet, ARP, Bridging)
*   Queuing discipline (佇列規則，用於流量控制)
*   Network device drivers (網路卡驅動程式)
![image](https://hackmd.io/_uploads/B1nrtVPxex.png)

### Linux Security Modules (LSM, 安全模組)

一個提供**強制訪問控制 (Mandatory Access Control, MAC)** 的框架：
*   透過在核心關鍵路徑插入鉤子 (hooks)，允許**載入不同的安全模組**來擴展預設的 Linux 安全模型 (基於 Discretionary Access Control, DAC)。
*   常見的 LSM 擴展包括：SELinux, AppArmor, Tomoyo, Smack。
:::

---

回[主目錄](https://hackmd.io/@Jaychao2099/Linux-kernel)