章節概覽#

本章提供 Linux 系統組成元件的高層次概觀。理解作業系統最有效的方式是透過 abstraction(抽象化)——忽略不必要的細節,專注於每個元件的基本用途與運作方式。

軟體開發者使用抽象化來建構作業系統與應用程式,將軟體劃分為稱為 component(元件)的子系統。本章會忽略各元件的內部技術細節,聚焦於它們在整體系統中的角色。

1.1 Linux 系統的抽象層次#

使用抽象化將運算系統拆分為元件,需要將元件組織成 layers(層次)或 levels(層級),依據元件在使用者與硬體之間的位置分類。

Linux 系統有三個主要層次:

  • Hardware(硬體):位於最底層,包含記憶體、CPU、磁碟、網路介面等
  • Kernel(核心):作業系統的核心,駐留在記憶體中,管理硬體並作為硬體與執行中程式之間的主要介面
  • User Processes(使用者行程):核心管理的執行中程式,統稱為 user space(使用者空間)

Figure 1-1: General Linux system organization

Kernel 與 user processes 的關鍵差異在於執行模式:

  • Kernel mode:擁有對處理器和記憶體的不受限制存取權,可能導致系統崩潰
  • User mode:僅能存取有限的記憶體子集和安全的 CPU 操作

User mode 的限制意味著,即使一個使用者行程崩潰,後果是有限的,kernel 可以清理它,不會影響系統中其他正在執行的行程。

Linux kernel 也可以執行 kernel threads,外觀類似行程但擁有 kernel space 的存取權。例如 kthreaddkblockd

1.2 硬體與主記憶體#

在所有硬體中,main memory(主記憶體)可能是最重要的。主記憶體本質上是一個大型儲存區域,由 0 和 1 組成,每個位置稱為一個 bit

  • 執行中的 kernel 和 processes 都是記憶體中的 bit 集合
  • 所有周邊裝置的輸入輸出都透過主記憶體傳遞
  • CPU 本質上是記憶體的操作器:從記憶體讀取指令與資料,再寫回記憶體

State(狀態)指的是記憶體中特定的 bit 排列。由於單一行程可能包含數百萬個 bit,實務上我們使用抽象術語來描述狀態,例如「行程正在等待輸入」或「行程正在執行啟動的第二階段」。

雖然常用 state 來指稱抽象狀態,image 這個術語指的是特定的實體 bit 排列。

1.3 Kernel#

Kernel 的工作幾乎都圍繞著主記憶體運作。它負責將記憶體分割給不同的子系統,並維護這些分區的狀態資訊。Kernel 管理四大系統領域:

  • Processes(行程管理):決定哪些行程可以使用 CPU
  • Memory(記憶體管理):追蹤所有記憶體的分配狀態——哪些分給特定行程、哪些共享、哪些是空閒的
  • Device drivers(裝置驅動程式):作為硬體與行程之間的介面
  • System calls and support(系統呼叫與支援):行程與 kernel 之間的溝通機制

1.3.1 行程管理 (Process Management)#

Process management 涵蓋行程的啟動、暫停、恢復、排程與終止。

在現代作業系統中,多個行程看似「同時」執行,但在單核 CPU 上,實際上同一時間只有一個行程佔用 CPU。每個行程使用 CPU 一小段時間後暫停,輪流執行。將 CPU 控制權從一個行程交給另一個行程的動作稱為 context switch(上下文切換)。

每段分配的時間稱為 time slice(時間片段),因為時間片段非常小,人類感知不到,系統看起來像是同時執行多個行程,這種能力稱為 multitasking

Context switch 的流程:

  1. CPU 根據內部計時器中斷目前行程,切換到 kernel mode
  2. Kernel 記錄 CPU 和記憶體的當前狀態
  3. Kernel 執行前一時間片段中累積的任務(如 I/O 操作)
  4. Kernel 分析就緒行程列表並選擇下一個行程
  5. Kernel 為新行程準備記憶體和 CPU
  6. Kernel 告訴 CPU 新行程的時間片段長度
  7. Kernel 切換 CPU 回到 user mode,將控制權交給行程

Context switch 回答了 kernel 何時運作的重要問題——它在行程時間片段之間執行。在多 CPU 系統中,多個行程可以真正同時執行。

1.3.2 記憶體管理 (Memory Management)#

Kernel 在 context switch 期間必須管理記憶體,需滿足以下條件:

  • Kernel 必須有自己的私有記憶體區域,user processes 無法存取
  • 每個 user process 需要自己的記憶體區段
  • 一個 user process 不可存取另一個行程的私有記憶體
  • User processes 可以共享記憶體
  • User processes 的部分記憶體可以是唯讀的
  • 系統可以使用磁碟空間作為輔助,使用超過實體記憶體的容量

現代 CPU 包含 MMU(Memory Management Unit,記憶體管理單元),實現稱為 virtual memory(虛擬記憶體)的記憶體存取方案。使用虛擬記憶體時,行程不直接以實體位置存取記憶體,而是由 kernel 為每個行程建立虛擬位址空間,MMU 負責將虛擬位址轉換為實體位址。

記憶體位址對應的實作稱為 page table

1.3.3 裝置驅動程式與管理 (Device Drivers and Management)#

Kernel 與裝置的角色相對簡單。裝置通常只能在 kernel mode 下存取,因為不當存取可能導致系統崩潰。

不同的裝置即使執行相同任務,也很少有相同的程式介面。因此 device drivers 傳統上是 kernel 的一部分,它們致力於為 user processes 提供統一的介面。

1.3.4 系統呼叫與支援 (System Calls and Support)#

System calls(或 syscalls)讓 user processes 可以執行單獨無法完成的任務。例如開啟、讀取、寫入檔案的操作都涉及 system calls。

兩個重要的 system calls:

  • fork():kernel 建立目前行程的近乎相同副本
  • exec():kernel 載入並啟動指定程式,取代目前行程

除了 init(參見第 6 章),Linux 系統上所有新的 user processes 都透過 fork() 建立,然後通常接著呼叫 exec() 來啟動新程式。例如在終端機輸入 ls 時:

# shell 呼叫 fork() 建立自身副本,副本再呼叫 exec(ls) 執行 ls
shell -> fork() -> copy of shell -> exec(ls) -> ls

Figure 1-2: Starting a new process

Kernel 也透過 pseudodevices(虛擬裝置)支援 user processes。Pseudodevices 看起來像裝置但完全以軟體實作,例如 /dev/random(kernel 亂數產生器)。

System calls 通常以括號表示(如 fork()),這個表記法來自 C 語言的呼叫方式。exec() 指的是一整個家族的相關 system calls。

1.4 User Space#

Kernel 為 user processes 分配的主記憶體稱為 user space。User space 也泛指所有執行中行程的記憶體集合。

Linux 系統中大部分的實際工作發生在 user space。從 kernel 的角度看,所有行程本質上是平等的,但它們為使用者執行不同的任務。User processes 存在一個基本的服務層次結構:

  • 底層:執行簡單、獨立任務的小型元件
  • 中間層:較大的元件,如郵件、列印、資料庫服務
  • 頂層:使用者直接控制的複雜應用程式

元件之間會互相使用。一般來說,如果一個元件要使用另一個,被使用的元件通常在相同或更低的服務層級。

Figure 1-3: Process types and interactions

大多數應用程式和服務會寫入稱為 logs 的診斷訊息。多數程式使用標準的 syslog 服務來寫入日誌,但有些程式自行處理日誌記錄。

1.5 使用者 (Users)#

Linux kernel 支援傳統的 Unix 使用者概念。User 是一個可以執行行程和擁有檔案的實體。每個使用者有一個 username,但 kernel 不管理使用者名稱,而是透過簡單的數字識別碼 user ID 來識別使用者。

Users 存在的主要目的是支援 permissions(權限)和 boundaries(邊界):

  • 每個 user-space process 都有一個 owner(擁有者)
  • 使用者可以終止或修改自己行程的行為,但不能干擾其他使用者的行程
  • 使用者可以擁有檔案並選擇是否與其他使用者共享

Root 是最重要的使用者,也稱為 superuser。Root 可以終止和修改其他使用者的行程、存取系統上的任何檔案。擁有 root access 的人就是系統管理員。

以 root 身份操作是危險的,因為系統允許你做任何事,即使對系統有害。因此系統設計者不斷嘗試減少需要 root 存取的場景。即使是 root 使用者,仍然運行在 user mode 而非 kernel mode。

Groups(群組)是使用者的集合,主要用途是允許群組成員之間共享檔案存取權。

1.6 展望#

本章描述了一個運行中 Linux 系統的組成:

  • User processes 構成你直接互動的環境
  • Kernel 管理行程與硬體
  • Kernel 和 processes 都駐留在 記憶體

這些是重要的背景知識,但光靠閱讀無法真正學會 Linux 系統的細節——你需要動手實作。下一章將從 user-space 基礎開始,同時介紹本章未討論的一個重要主題:長期儲存(磁碟、檔案等)。