# 第一講:作業系統術語及概念 > 本筆記僅為個人紀錄,相關教材之 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)