JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

作業系統究竟在做什麼?

在任何行程、分頁或檔案說得通之前,你得先站穩底層樓:作業系統究竟是什麼、那條守護一切的界線,以及程式如何禮貌地請求幫忙。

一個程式,三份工作

從你按下電源鍵的那一刻,到關機為止,有一個程式默默掌管著一切:作業系統。人們很容易以為作業系統就是桌布、開始功能表或應用程式商店,但那些只是隨附的程式。真正的作業系統是夾在你的應用程式與裸機之間的那一層,而它同時在做三份工作。

第一,它是資源管理者。一台電腦能分配的東西就那麼多——少數幾個 CPU 核心、固定容量的記憶體、一顆磁碟、一個螢幕——但你執行的數十個程式,每個都表現得彷彿自己獨佔整台機器。就像一座住滿廚師的共用廚房,若沒有管理者決定誰用爐子、用多久,必定一團亂。第二,它是抽象層:與其強迫每個應用程式都得懂你這顆磁碟的精確電氣指令,它提供「開啟一個檔案」或「送出這些位元組」這類乾淨、統一的概念。第三,它是控制程式:它監看執行中的程式、阻止出錯的程式拖垮整台機器,並執行「誰能做什麼」的規則。

幾乎每一台裝置都有作業系統,即使你從沒見過它:你的手機、筆電、網站背後的伺服器,甚至微波爐裡的晶片。本主題其餘的一切——行程、排程、分頁、檔案——其實都只是對作業系統默默替你承擔的這三份工作之一的進一步細看。

分層的機器:硬體、作業系統、應用程式

把電腦想清楚最好的方式,是把它看成一疊層次,就像建築的樓層,每一層都靠在下一層之上,並對上一層提供服務。最底層是硬體——CPU、記憶體、磁碟、裝置——那是一台只能執行原始指令的機器。最頂層是你與你的應用程式。作業系統是中間那關鍵的一層,而你做的幾乎每件事,都會順著它往下流、再往上返回。

把軟體分成兩個家族也很有幫助。系統軟體的存在是為了讓電腦本身運轉並提供支援——作業系統、它的驅動程式、把程式準備好以便執行的連結器與載入器。應用軟體的存在則是為了完成你真正在乎的任務——瀏覽器、遊戲、試算表。粗略的判準是:若一個程式主要服務機器或其他程式,它就是系統軟體;若它主要服務你的目標,它就是應用程式。應用程式把所有低階的事都倚賴作業系統,請它去開檔案、在螢幕上繪圖,而不是自己碰觸硬體。

核心與那道大分界

作業系統的核心地帶是核心(kernel)——最內層、最受信任的部分,那個始終在執行、且對硬體擁有完全權力的程式。剝去選單、視窗系統與隨附的應用程式,剩下的就是核心。如果作業系統是旅館員工,核心就是握有萬能鑰匙的大樓管理員:它能進入任何房間、操作任何機器,其他人都得透過它。

整個計算領域中最重要的那條界線,就在此處現身。CPU 在兩種模式之一中執行,而執行規則的是硬體本身——這就是雙模式運作。在使用者模式下,一般程式可以做自己的算術、只能存取被授予的記憶體,但若它嘗試一條危險的特權指令——直接命令裝置、改寫記憶體映射、關閉中斷——硬體會拒絕,並陷入(trap)到作業系統。在核心模式下,所有指令都被允許;核心便在此執行。一個單一的硬體旗標,也就是模式位元,記錄 CPU 此刻處於哪種模式,硬體在每次特權動作時都會查看它。關鍵在於:使用者程式不能直接把這個位元設成核心——若它能,整個保護機制就會崩潰。

為何要為這一條線如此講究?因為它是整個系統的穩定與安全界線。一般應用程式的程式錯誤只會讓那個程式當掉,其他什麼事都沒有;而核心被託付了完整的硬體權力,它的程式錯誤卻可能讓整台機器當掉或淪陷。這正是為什麼作業系統要如此努力地把核心保持得小巧、謹慎、難以被愚弄。

那道門:系統呼叫

如果使用者模式的程式不能自己碰觸硬體,那它究竟怎麼讀檔案或送封包?它去請求。系統呼叫是從使用者模式跨入核心唯一受控的那道門——官方、有人看守的通道。想像一間銀行:你不能走進金庫拿現金,但你可以走到櫃員窗口、填一張單,請求提款。櫃員(核心)受信任、待在櫃檯後面,他檢查你的請求,並代你完成那項特權工作。

具體來說,當你的程式碼呼叫類似「read(fd, buf, n)」的東西時,一條特殊的陷阱指令會把模式位元切成核心,並跳到作業系統事先選定的固定處理常式。以下就是這趟旅程,一步一步來看。

  1. 你的程式準備好請求(要呼叫哪一個、帶哪些參數——檔案描述符、緩衝區、要幾個位元組),然後執行那條陷阱指令。
  2. 硬體不可分割地把模式位元翻成核心,並跳進作業系統的陷阱處理常式——控制權此刻已在核心之內。
  3. 核心檢查這個請求:你有權讀這個檔案嗎?參數合法嗎?若不行,它拒絕並回傳一個錯誤。
  4. 若被允許,核心便去做那項特權工作——它向磁碟索取位元組,並把它們複製進你的緩衝區。
  5. 核心把模式位元翻回使用者並返回,你的程式從中斷之處恰好接續下去,此時已拿到它要的資料。

許多程式同時跑——以及這一切如何開始

早期的電腦一次只跑一份工作,由上到下,而那份工作一暫停下來讀磁碟,昂貴的 CPU 就閒置在那裡。多工程式設計解決了這個問題:同時把好幾個程式留在記憶體裡,每當正在跑的那個等待輸入輸出時,就把 CPU 交給另一個。把同樣的想法推到親切的極致,就得到分時系統——切換程式的速度快到每秒鐘數十次,讓每位使用者都覺得整台機器是自己獨享的。正是這種快速切換,讓你的音樂在下載進行、聊天視窗開著時仍持續播放:作業系統正把唯一的 CPU 切成一個個小小的輪次。

但在任何作業系統存在來載入它之前,作業系統本身究竟是怎麼最初被載入的?這個「自我啟動」的難題由開機程序解決:開機時,一個烙進韌體裡的小程式最先執行,它在磁碟上找到核心、把它載入記憶體,然後交出控制權。從那第一道指令起,核心便接管一切。而核心要怎麼構築,是個真實的設計抉擇——也就是它的結構單核心把幾乎所有東西(排程、記憶體、驅動程式、檔案系統)都放進一個龐大的特權程式裡:快,因為各部分彼此直接呼叫,但任何一處的程式錯誤都可能拖垮全部。微核心只把最低限度留在核心模式,其餘推到以訊息溝通的使用者模式服務:更強健、更容易隔離,但它在訊息傳遞的額外開銷上付出真實的代價。混合核心則折衷兩者。沒有哪一種自動「比較好」——這是一場取捨,而本階梯接下來的幾篇指南,會逐一打開這些門。