Learning Objectives
- 說明作業系統的兩個角色:管理硬體資源、提供服務給應用程式
- 分辨使用者模式與核心模式,說明系統呼叫為什麼存在
- 說出核心的主要子系統(行程管理、記憶體管理、檔案系統、網路、驅動程式)各自負責什麼
- 比較 Windows、macOS、Linux、Android、iOS 的核心、應用程式介面與常見用途
同時開很多程式,為什麼不會打架
你的手機可能同時在播音樂、收訊息、用地圖導航。這幾個程式都要用同一顆 CPU、同一塊記憶體、同一個喇叭, 卻不會互相覆蓋資料,也不會兩首歌一起從喇叭冒出來。負責安排這一切的軟體,就是作業系統(operating system,OS)。
作業系統有兩個角色:
| 角色 | 做什麼 | 例子 |
|---|---|---|
| 資源管理者 | 決定 CPU、記憶體、儲存空間、各種裝置給誰用、用多久 | 讓音樂與地圖輪流使用 CPU;替每個程式劃出自己的記憶體 |
| 服務提供者 | 把複雜的硬體包裝成簡單的服務,讓應用程式不必自己處理 | 「開檔案」「存檔」「連上網路」「畫一個視窗」 |
所以寫應用程式的人不需要知道 SSD 用哪一種控制晶片、網路卡是哪一家的。他只要請作業系統「把這段文字存進 report.txt」, 剩下的事由作業系統完成。
這一課要回答:
- 應用程式要怎麼「請」作業系統做事?為什麼不能自己直接操作硬體?
- 作業系統的核心裡面分成哪幾個部分?
- Windows、macOS、Linux、Android、iOS 有什麼相同、什麼不同?
作業系統的發展
最早的電腦沒有作業系統:操作員把程式(打孔卡片)放進讀卡機,一次跑一個,跑完再換下一個,電腦常常閒著等人。 後來出現的作業系統,最早的工作就是自動接著執行下一個工作(批次處理),並提供大家共用的輸入輸出程式。 例如 1956 年通用汽車研究實驗室與北美航空為 IBM 704 電腦開發的 GM-NAA I/O,常被認為是最早用在實際工作上的作業系統之一。
之後的重要里程碑:
| 年份 | 事件 |
|---|---|
| 1969 | 貝爾實驗室的 Ken Thompson 與 Dennis Ritchie 開始開發 UNIX;許多後來的系統都受它影響 |
| 1985 | Microsoft 推出 Windows 1.0,當時是在 MS-DOS 上執行的圖形介面 |
| 1991 | 芬蘭大學生 Linus Torvalds 發表 Linux 核心,之後由全球社群共同開發 |
| 1993 | Windows NT 3.1 推出;現在的 Windows 都建立在 NT 架構上 |
| 2001 | Apple 推出 Mac OS X(現在叫 macOS),核心來自開放原始碼的 Darwin |
| 2007 | 第一代 iPhone 上市,作業系統當時叫 iPhone OS,2010 年改名 iOS |
| 2008 | 第一支 Android 手機上市;Android 使用修改過的 Linux 核心 |
作業系統讓「一台電腦同時給很多人、很多程式用」成為可能:從批次處理,到很多使用者輪流使用的分時系統,再到今天一個人同時開幾十個程式。
核心、使用者模式與系統呼叫
作業系統最重要的部分叫核心(kernel)。開機時,電腦的韌體(UEFI 或 BIOS)先啟動一個小小的開機載入程式, 由它把核心載入記憶體;核心接手後一直留在記憶體裡,直到關機。
CPU 有兩種執行模式:
| 模式 | 誰在這個模式執行 | 能做什麼 |
|---|---|---|
| 使用者模式(user mode) | 一般的應用程式:瀏覽器、文書軟體、遊戲 | 只能做一般的計算、存取自己的記憶體;不能直接操作硬體 |
| 核心模式(kernel mode) | 作業系統核心 | 可以執行所有指令,包括控制硬體的特權指令 |
應用程式需要硬體做事時,必須透過系統呼叫(system call)請核心幫忙。呼叫的那一刻,CPU 從使用者模式切換到核心模式; 核心檢查這個要求合不合法(例如你有沒有權限讀這個檔案),做完之後再切回使用者模式,把結果交給應用程式。
Linux 上常見的系統呼叫:
| 系統呼叫 | 用途 |
|---|---|
open、read、write、close |
開檔、讀、寫、關檔 |
fork、execve、exit |
建立行程、載入程式、結束行程 |
mmap |
要一塊記憶體 |
socket、connect、send |
網路連線 |
你寫程式時很少直接寫系統呼叫。例如 Python 的一行:
print('你好')
Python 會把文字編碼成位元組,最後透過系統呼叫(在 Linux 上是 write)請核心把它送到螢幕(終端機)上。
為什麼要分兩種模式?如果任何程式都能直接操作硬體,一個有錯的程式就可能把整顆硬碟寫壞,或讀走別人的資料。 分開之後,核心像唯一的櫃台,所有要求都要經過它檢查。
核心裡面有什麼
核心的工作可以分成幾個子系統:
| 子系統 | 負責 | 後面的課 |
|---|---|---|
| 行程管理 | 建立與結束行程(執行中的程式),決定下一個由誰使用 CPU | 第 16 課 |
| 記憶體管理 | 替每個行程配置記憶體、讓行程之間互不干擾、記憶體不夠時把資料暫存到磁碟 | 第 17 課 |
| 檔案系統 | 檔名、目錄、權限,以及檔案放在磁碟的哪些區塊 | 第 18 課 |
| 網路 | TCP/IP 等協定:把資料切成封包、加上位址、處理連線 | 網路相關的課 |
| 驅動程式 | 把核心的要求翻譯成某個硬體看得懂的命令 |
驅動程式(driver)讓同一個作業系統可以搭配成千上萬種硬體:新的印表機只要附上驅動程式,作業系統就會用。 硬體有事要通知核心時(按鍵被按下、網路封包到了、SSD 讀完了),會送出中斷(interrupt),讓 CPU 暫停手邊的工作,先去處理。
不同作業系統把這些子系統放的位置不太一樣:
- 單體式核心(monolithic kernel):全部子系統都在核心模式裡,彼此直接呼叫,速度快。Linux 屬於這一類,驅動程式可以做成模組、需要時再載入。
- 微核心(microkernel):核心只留最基本的功能,檔案系統、驅動程式等放到使用者模式,以「傳訊息」溝通;一個部分壞了不會拖垮整個核心,但溝通的成本比較高。
- 混合式核心(hybrid kernel):介於兩者之間。Windows 的 NT 核心、macOS 與 iOS 的 XNU 核心通常被歸在這一類。
想一想:模式與系統呼叫
文書軟體要把檔案存到 SSD,下面哪一個描述正確?
下面哪一件事通常不需要系統呼叫?
「新買的網路攝影機接上電腦後,作業系統要先裝好什麼才能使用它?」
常見的作業系統
| 作業系統 | 核心 | 常見裝置 | 原始碼 |
|---|---|---|---|
| Windows | Windows NT 核心 | 個人電腦、筆電、伺服器 | 不公開 |
| macOS | XNU(屬於 Darwin) | Apple 的 Mac 電腦 | Darwin 公開,其餘不公開 |
| Linux | Linux 核心 | 伺服器、雲端主機、超級電腦、嵌入式裝置、個人電腦 | 開放原始碼(GPL 授權) |
| Android | 修改過的 Linux 核心 | 各廠牌的手機、平板、電視、手錶 | 基礎系統(AOSP)開放原始碼,Google 的服務不公開 |
| iOS | XNU(和 macOS 同一個核心) | iPhone | 不公開 |
幾個常被混淆的地方:
- Linux 嚴格來說只是核心。 我們平常說的「Linux 系統」,是核心加上許多工具與桌面程式組成的發行版(distribution),例如 Ubuntu、Debian、Fedora。
- UNIX 家族。 macOS 的 Darwin 有一部分來自 BSD(一種 UNIX);Linux 則是仿照 UNIX 的設計、但程式碼從頭寫起,所以常被稱為「類 UNIX」系統。
兩者的命令列指令(
ls、cd、cp…)因此很像。 - 手機作業系統的限制更多。 每個 App 被關在自己的「沙箱」裡,要用相機、位置、聯絡人都要先取得你的同意;系統也會積極暫停背景的 App 以節省電力。
應用程式是寫給某個作業系統的:它呼叫的是那個作業系統的介面(例如 Windows API、Apple 的 Cocoa),
執行檔的格式也不同。所以 Windows 的 .exe 不能直接在 Mac 上執行,Android 的 App 也不能直接裝到 iPhone 上。
想一想:常見的作業系統
下面哪一個說法正確?
一家公司要架網站伺服器,想要免授權費、可以自己修改系統,最可能選哪一個?
重點整理
- 作業系統是資源管理者(CPU、記憶體、儲存、裝置給誰用),也是服務提供者(檔案、網路、視窗)。
- 核心開機後常駐記憶體。CPU 分使用者模式與核心模式;應用程式不能直接碰硬體,要透過系統呼叫請核心處理,每次呼叫都會切換到核心模式再切回來。
- 核心的主要子系統:行程管理、記憶體管理、檔案系統、網路、驅動程式;硬體用中斷通知核心。
- 核心的架構有單體式(Linux)、微核心、混合式(Windows NT、XNU)。
- Windows 用 NT 核心;macOS 與 iOS 都用 XNU;Linux 是核心,Ubuntu 等是發行版;Android 用修改過的 Linux 核心。應用程式依賴作業系統提供的介面,所以不能直接跨作業系統執行。
下一課看行程管理的核心問題:只有幾個 CPU 核心,卻有幾百個行程要執行,作業系統怎麼決定下一個輪到誰。 想實際操作 Linux 的命令列,可以接著上 Linux 軌。