本章節講作業系統的架構。
一開始會先看電腦的層級,接著講 system call 與 API 的差異,最後則會帶到 OS 的類型。
電腦的層級
OS 是系統唯一的 manager,他所提供的 interface 是唯一可以 access 到共用資源的介面。因為 OS 在幫使用者做事、在服務使用者,所以它所含的各個 subsystem 又叫做 service。
一般 OS 會包含下面這些 services:
- UI 使用者介面
- 執行 User Program
- I/O
- 檔案系統管理
- Communication
- 錯誤偵測
- 資源控管
- Accounting
- protect & security
7,8,9 都是為了讓電腦能運作的、OS 內部的功能。而本文只關係到 1,5,剩下的章節會獨立於其他篇筆記。
使用者介面 User Interface
- Command Line Interface
- Cli 都會有一層叫做 Shell 的 Commend Line interpreter,用途是讓每個使用者可以根據自己的習慣進行設定,也就是 customization。
- Graphic User Interface
Communication
- 電腦間的溝通 (networking)
- 程式間的溝通
透過 memory 的使用可以區分成兩大類:
- message passing
- shared memory
message passing
A 程式去叫 OS 把 A memory 的資料複製到 OS 的 memory,另一支程式再透過 OS 將資料從 OS 的 memory 複製到 B memory。
(要注意不是直接從 A 複製到 B memory,因為有 protection。)
壞處是比較慢,因為資料要 copy 來 copy 去的。
shared memory
概念很簡單,就是直接讓某一塊 memory 能夠同時被 A,B 程式 access 就好了。不過要做到這件事,也是需要先 call system call。
一般的程式預設是沒有這塊共享的 memory 區段的,不過 multi-thread programming 的程式預設就會有了。
壞處是可能會有 deadlock synchronization,未來的章節會講到,這邊不提。
Application Program Interface v.s System Call
講完了基本的 OS 要處理的基本功能,就來講 API 與 system 的差異。
system call
- 較底層,屬於 OS 的一部份,是 OS 所提供的 function call、唯一的 interface。
- 會觸發 software interrupt(因為要進到 kernel mode)
- written in assembly(因為講求效能)
但不是人人都會寫 assembly 啊,所以就會再多一層 API。
API
API 是為了方便開發的 interface。
system call & API 之間不見得是一對一,有可能一對多,甚至一對零。 因為兩者的目的是完全不同的。
system call 希望越少越好,兩個 system call 之間的交集越少越好,最好完全沒關聯,code 越少則越好維護;而 API 則是希望使用者越方便 call 越好,所以有可能只是純數字運算(e.g., abs),這樣就不會 call 到 system;當然也有可能會需要多個 system call 才能完成一個 API 想達到的目的,重點是 使用者方便使用。
兩大派別的 API
- Windows: Win32
- POSIX: Linux, Mac …
= protable operation system interface for Unix
API 的存在意義?
- 簡單
- 能用比較 user friendly 的語言去寫程式。
- Protable
- 因為是人訂的標準,所以只要照著標準走,換個同標準的 OS,程式也不用重寫。
- 效率(寫的效率、不是跑的)
- 不是每個 function 都需要 OS service 或 invoke kernel。
- 有的人不知道某個時候需不需要 system call,所以無腦使用已經最佳化過的 API 就不用擔心太多。
System Call 怎麼傳參數的?
一般來說有三種方式:
- 寫到 register,CPU 讀固定的 register 就能得到值。
- 把資料存在 memory,然後把存資料的 address 丟去 register 給 system call 當參數。
- 把資料丟進 stack,然後讓 OS 把資料 pop 出來。
作業系統的架構
- Simple OS Architecture
- Layer OS Architecture
- Microkernel OS
- Modular OS Structure
- Virtual Machine
- Java Virtual Machine
使用者的目標和作業系統的設計目標不同
- 使用者的目標
- 易用
- 穩定
- 安全
- 反應快速
- 作業系統
- 容易設計、實作、維護
- 穩定
- 無 error
- 執行程式的效率高
因為兩者的需求可能會互相衝突,所以我們就有了許多種不同的架構。
Simple OS Architecture
整層電腦只有:
- BIOS driver
- hardware drive
- OS
- application
Simple 就是 OS 整個都融在一起,完全沒分,function 隨便放、隨便 call。
缺點是不安全、難以 maintain/enhance。
Windows 早期就是這個設計,不過因為他是公司,所以 maintain 的問題不大。但放到現在來看的話,這種架構的 OS 就完全不可能成為一個開源專案。
Layer OS Architecture
把所有 service 切成一個個的 layer, 從 layer0 一層層往上疊 N 層。
高層可以 call 低層的 function,但低層不能 call 高層的。像 memory 可以 call I/O 的 function call,但反過來就不被允許。
好處是很容易 debug,因為不會上下亂 call,只會往上 call 而已,所以除錯的時候不會繞來繞去,只要找一個方向就好。
而缺點則如下:
- 因為硬是把它切開,所以變得很難去 define 一個層。
- 較無效率
- 要用到某個設計所不允許的 feature 就會繞來繞去、破壞 layer。
- 因為是 layer,所以就需要一層層 call function,然後一直 memory copy。
Linux 早期就是這樣的設計。
Microkernel OS
- kernel 的程式碼越小、越少就越好 (Micro 的真諦)
- 因為越小越容易維護,也更穩定。
- 有 modulize 的概念:kernel 只負責在 module(subsystem) 之間進行溝通,而 subsystem 則是 run 在 user space 中。(subsystem 不是 OS 的一部分。)
- 所以可以任意置換各種 subsystem,只要把他 hook 起來就行了。
- 優點
- 很容易擴充&Port。
- 缺點
- 效能非常糟糕:因為 subsystem 之間要溝通就必須透過 kernel,所以就會有 滿滿的 system call & 滿滿的 interrupt;又因為想避免 synchronize 的問題,所以參數的傳遞都是透過 message passing,就會有 滿滿的 memory copy。
IoT 的裝置是往這個方向去走的。
Modular OS Structure
現代常見的 OS 都是這個架構。
- 結合 module 與 simple 的概念,把 module 都納進 kernel 裡面。
- 這樣就避免了一堆浪費資源的 system call、message passing,也比較好維護、比較有彈性。
- 只要把 module load 進來,就可以變成 kernel 的一部分。
OS 會有一個專門放 system call function 的 table,所以只要有足夠的權限就可以進行修改。可以自行去網路上找教學玩玩看。
Virtual Machine
把底層抽象化,即使已經有一個 OS,甚至只是軟體,也把他抽象得像硬體一樣。
(我們一般用 host 指真正的系統,guest 指架在上面的虛擬的系統。)
因為 VM 的 kernel 對於 host system 來說,其實是在 user space 中,所以在跑 privileged instruction 的時候,他其實是 run 在 user mode,因此就會 fail。
解法也很簡單,host OS 在 VM call privileged instruction 時就會接到
interrupt,當 OS 接到 interrupt 且發現是 VM 想 call 的話,就幫他 call,
這樣就能跑 VM 想跑的 privileged instruction 了。
所以缺點也很明顯:慢。VM 的 privileged instruction 引發了兩次 interrupt
(一次是 error detected interrupt,一次是 host OS 幫呼叫 system call 的 interrupt),平常只要 call 一次,那加倍 call 時間當然就會增加。
VM 因為 Critical Instructions 的存在所以很難達成:
- Critical Instructions 是一種奇妙的指令,他在 user space 和 kernel space 都能執行,而且結果會不一樣。
- 因此,原本想靠 error detected 拋出 interrupt 讓 system 去接的方法就不能用了。
VM 的好處?
- protection
- 因為有比較好的 isolation,所以不同 VM 之間不會互相干擾。
- compatibility
- 方便研究與開發
- 在開發 OS 的時候一開始當然會有很多 bug,但不希望每次 run 都要重裝,一個小地方錯了又整台電腦 crash,有 VM 就可以在上面裝正在開發的 OS 而不影響 host OS。
- honeypot
- 雲端計算
- 因為要資源共享,且要確保資源的使用率是高的。
- 不過藉由 VM 來實現雲端計算的資源共享只是其中一個方式,
不是 the only one way,其他還有容器之類比較輕量的方式。
兩種 VM 類型
- Full virtualization
- guest OS 的程式碼完全不用動,就能夠裝在 VM 中。
- e.g., VMWare, KVM
- Para-virtualization
- 存在一個知道所有 VM 的 master 程式(或稱為 manager 程式),且 guest OS 也需要被修改
- 多一個 master 程式不見得效能會比較差:
- 因為大多 OS 都是為了單一硬體設計的,但 VM 並非如此
- 這邊舉了 sequential 的 file system 作為例子:
每個系統都覺得 sequential 是最有效率的,如果大家都 sequential,那 sequential + sequential = random。就變得沒有效率了。而 para-virtualization 有 manager 可以在傳給 OS 時再做一次 optimize,效能就可能會比較好。
- e.g., Xen
Java Virtual Machine
- base on virtual machine 的概念去設計的。
- 因為目的是 run instruction,所以 JVM 的重點只有 code translation 而已。
- 雖然 instruction 一行行翻會很慢,但因為 Java 有 JIT 這個 compile 所以省了不少時間。