1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
您的問題非常深入!這觸及了作業系統最底層的保護機制。理解這些「模式」對於掌握作業系統如何確保安全和穩定至關重要。

---

### Kernel 的「核心模式」與其他模式

作業系統的設計,特別是現代多工(multitasking)作業系統,必須確保程式之間以及程式與作業系統本身之間不會互相干擾,更不能讓惡意或錯誤的程式損害整個系統。為了實現這一點,CPU 和作業系統引入了不同的**執行模式(Execution Modes)**,也稱為**特權級別(Privilege Levels)**。

#### 什麼是核心模式(Kernel Mode / Supervisor Mode / Ring 0)?

**核心模式是 CPU 最高的特權級別。** 在這個模式下,CPU 可以執行**所有指令**,包括那些直接操作硬體(如讀寫磁碟、存取記憶體控制器、設定 CPU 暫存器)的特權指令。

* **完全掌控:** 當 CPU 處於核心模式時,作業系統核心擁有對系統硬體的完全、不受限制的訪問權限。它可以讀寫所有記憶體、直接控制任何 I/O 裝置、管理 CPU 的排程等。
* **高風險:** 也因為權限極高,核心模式下的任何錯誤或惡意程式碼都可能導致整個系統崩潰(通常是所謂的「核心崩潰」或「藍屏死機」/「內核恐慌」)。
* **執行者:** 只有作業系統核心的程式碼(以及核心模組、驅動程式)才能在核心模式下執行。使用者應用程式不能直接進入核心模式。

#### 除了核心模式還有什麼模式?

最常見的另一個模式是:

* **使用者模式(User Mode / Ring 3)**:
* **受限權限:** 這是 CPU 權限最低的模式。在使用者模式下,CPU 只能執行**非特權指令**。這意味著程式不能直接訪問硬體、不能直接修改系統的重要配置、不能直接操作其他程序的記憶體空間等。
* **安全沙盒:** 使用者模式為每個應用程式提供了一個相對安全的「沙盒」。如果一個應用程式在使用者模式下崩潰,通常只會影響它自己,而不會拖垮整個作業系統或其他應用程式。
* **執行者:** 所有的使用者應用程式(例如瀏覽器、文字處理器、遊戲、Bash Shell、Python 直譯器,以及您自己編寫的程式)都在使用者模式下執行。

有些 CPU 架構可能有更多中間的特權級別(例如 Ring 1, Ring 2),但最核心和廣泛使用的是「核心模式」和「使用者模式」。

---

### 核心模式是指記憶體跟 CPU 協作的情況嗎?

**核心模式不僅僅是指記憶體和 CPU 的協作情況,它更是一個 CPU 的「狀態」,定義了 CPU 當前能執行什麼樣的指令和能訪問什麼樣的資源。**

然而,核心模式的運作確實與**記憶體管理單元(MMU)** 和 **CPU 的暫存器**密切協作,以實現其特權功能:

* **CPU 模式暫存器:** CPU 內部有特殊的暫存器,儲存了當前的特權級別(例如,0 表示核心模式,3 表示使用者模式)。每次執行指令前,CPU 都會檢查這個暫存器,根據當前模式來決定是否允許執行該指令。
* **記憶體保護:** 在核心模式下,核心可以配置 **MMU**,來設定哪些記憶體區域可以被訪問、哪些不可以,以及不同特權級別的程式可以訪問哪些記憶體。
* 例如,核心會將自身的記憶體區域標記為「只有在核心模式下才能訪問」。
* 使用者模式的程式只能訪問被 Kernel 分配給它的記憶體空間。如果它嘗試訪問其他程序的記憶體或核心的記憶體,MMU 會偵測到這是非法的,並發出一個**硬體中斷**(稱為「頁錯誤」或「段錯誤」),將控制權交回給 Kernel 處理。

所以,可以說核心模式是 CPU 在最高權限下,與其記憶體管理單元及其他硬體協同工作,來管理和控制整個系統資源的狀態。

---

### Kernel 檢查請求合法性的具體工作與原因

當使用者程式(例如 Bash 或 Python 直譯器)發出一個**系統呼叫(System Call)**,請求 Kernel 提供服務時,Kernel 會執行一系列檢查,這就是您提到的「檢查請求的合法性」。

#### 具體來說,Kernel 會進行哪些工作以完成檢查?

當一個系統呼叫被觸發時(透過特定的指令,例如 x86 架構上的 `SYSCALL` 指令),會發生以下步驟:

1. **模式切換:** CPU 會從「使用者模式」切換到「核心模式」。這是自動且受保護的,只有通過系統呼叫這樣的受控機制才能完成。
2. **呼叫參數檢查:**
* **引數數量與類型:** Kernel 會檢查系統呼叫的引數數量是否正確、類型是否符合預期。例如,`open()` 呼叫需要檔案路徑和模式參數。
* **指針有效性:** 如果參數中包含記憶體地址(指針),Kernel 會檢查這些指針是否指向使用者程式可以合法訪問的記憶體區域。它會防止使用者程式傳遞一個指向核心記憶體或另一個程式記憶體的指針來進行惡意操作。
3. **權限檢查:**
* **檔案權限:** 如果請求涉及檔案操作(如讀寫檔案),Kernel 會檢查發出請求的使用者或程序是否有足夠的權限來執行該操作(例如,是否有權限讀取 `/ etc/shadow` 檔案)。
* **資源權限:** 檢查程序是否有權限使用特定的硬體資源或執行特定的特權操作。
4. **資源限制檢查:**
* **配額:** Kernel 會檢查程序是否超過了其被分配的資源限制,例如記憶體使用量、打開的檔案描述符數量、創建的程序數量等。
5. **安全性檢查:**
* 防止某些惡意行為模式,例如嘗試注入惡意程式碼、繞過安全機制等。
* 沙盒化和容器技術(如 Docker)也依賴 Kernel 進行更嚴格的資源隔離和安全檢查。

#### 為什麼需要檢查請求的合法性?

檢查請求合法性是**作業系統安全和穩定性的基石**,原因如下:

1. **系統穩定性:**
* 如果一個錯誤的程式碼向 Kernel 發出不合法的請求(例如,嘗試寫入只讀的系統檔案,或訪問不存在的記憶體地址),未經檢查的請求可能導致 Kernel 內部數據損壞,進而導致整個系統崩潰。
2. **安全性:**
* 防止惡意軟體:惡意軟體可能會嘗試利用系統呼叫來提升權限、讀取敏感數據、感染其他程式或破壞系統。合法性檢查是防止這些攻擊的第一道防線。
* 隔離不同程式:確保一個程式無法干擾或竊取另一個程式的數據。
3. **資源管理:**
* 強制執行資源配額,防止單一程式耗盡所有系統資源,導致其他程式或整個系統無法正常運作。
4. **多工環境的必要:**
* 在多個程式同時運行的環境中,Kernel 必須充當「仲裁者」,公平合理地分配資源,並確保各個程式在自己的沙盒中運行,互不影響。

簡而言之,**核心模式是 Kernel 執行特權操作的「專屬工作區」**,而**合法性檢查是 Kernel 確保系統安全和穩定的「守門人」**。沒有這些機制,現代多工作業系統將無法可靠地運作。