Wildsky F.

Easy things should be easy, and hard things should be possible.



作業系統 Ch2-3 – Struture

Posted on

本章節講作業系統的架構。

一開始會先看電腦的層級,接著講 system call 與 API 的差異,最後則會帶到 OS 的類型。

電腦的層級

OS 是系統唯一的 manager,他所提供的 interface 是唯一可以 access 到共用資源的介面。因為 OS 在幫使用者做事、在服務使用者,所以它所含的各個 subsystem 又叫做 service。

一般 OS 會包含下面這些 services:

  1. UI 使用者介面
  2. 執行 User Program
  3. I/O
  4. 檔案系統管理
  5. Communication
  6. 錯誤偵測
  7. 資源控管
  8. Accounting
  9. protect & security

7,8,9 都是為了讓電腦能運作的、OS 內部的功能。而本文只關係到 1,5,剩下的章節會獨立於其他篇筆記。

使用者介面 User Interface

  1. Command Line Interface
    1. Cli 都會有一層叫做 Shell 的 Commend Line interpreter,用途是讓每個使用者可以根據自己的習慣進行設定,也就是 customization。
  2. Graphic User Interface

Communication

  • 電腦間的溝通 (networking)
  • 程式間的溝通

透過 memory 的使用可以區分成兩大類:

  1. message passing
  2. 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

  1. Windows: Win32
  2. POSIX: Linux, Mac …
    = protable operation system interface for Unix

API 的存在意義?

  • 簡單
  • 能用比較 user friendly 的語言去寫程式。
  • Protable
  • 因為是人訂的標準,所以只要照著標準走,換個同標準的 OS,程式也不用重寫。
  • 效率(寫的效率、不是跑的)
  • 不是每個 function 都需要 OS service 或 invoke kernel。
  • 有的人不知道某個時候需不需要 system call,所以無腦使用已經最佳化過的 API 就不用擔心太多。

System Call 怎麼傳參數的?

一般來說有三種方式:

  1. 寫到 register,CPU 讀固定的 register 就能得到值。
  2. 把資料存在 memory,然後把存資料的 address 丟去 register 給 system call 當參數。
  3. 把資料丟進 stack,然後讓 OS 把資料 pop 出來。

作業系統的架構

  1. Simple OS Architecture
  2. Layer OS Architecture
  3. Microkernel OS
  4. Modular OS Structure
  5. Virtual Machine
  6. Java Virtual Machine

使用者的目標和作業系統的設計目標不同

  • 使用者的目標
  1. 易用
  2. 穩定
  3. 安全
  4. 反應快速
  • 作業系統
  1. 容易設計、實作、維護
  2. 穩定
  3. 無 error
  4. 執行程式的效率高

因為兩者的需求可能會互相衝突,所以我們就有了許多種不同的架構。

Simple OS Architecture

整層電腦只有:

  1. BIOS driver
  2. hardware drive
  3. OS
  4. 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 而已,所以除錯的時候不會繞來繞去,只要找一個方向就好。

而缺點則如下:

  1. 因為硬是把它切開,所以變得很難去 define 一個層。
  2. 較無效率
  • 要用到某個設計所不允許的 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 都是這個架構。

  • 結合 modulesimple 的概念,把 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 類型
  1. Full virtualization
    • guest OS 的程式碼完全不用動,就能夠裝在 VM 中。
    • e.g., VMWare, KVM
  2. 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 所以省了不少時間。

ref: