作業系統作為抽象層
真實硬體既雜亂又不一致。某顆磁碟講一套低階指令,另一顆講另一套;某張網路卡有自己古怪的暫存器。如果每個程式都得懂每個裝置的精確細節,軟體將無從寫起。作業系統把這一切藏在一小組乾淨、統一的概念之後。這就像開車:你轉動方向盤、踩踏板,從不去想噴油嘴、點火正時或差速器。簡單的操控,是對一台極其複雜機器的抽象。
作業系統提供的最強大抽象有:檔案(一段有名字、可成長的位元組串流,你可以開啟、讀取、寫入、關閉,無論它存在於旋轉磁碟、固態硬碟還是隨身碟上)、行程(一個執行中的程式,看起來彷彿擁有自己專屬的 CPU 與專屬的記憶體),以及統一的輸入輸出(你用同一組基本操作從鍵盤、檔案或網路插座讀取資料)。在底層,作業系統把每個乾淨的請求翻譯成真實硬體所需的特定、醜陋的指令——但程式永遠不必看見這層翻譯。
這正是為什麼同一個應用程式能在磁碟與晶片差異極大的機器上執行:它對作業系統的抽象說話,而作業系統對硬體說話。抽象層也促成了可攜性與保護——因為程式透過作業系統乾淨的介面,而非直接碰觸硬體,作業系統便能檢查並控制每一次存取。誠實的提醒是:抽象會「漏」——檔案感覺像一條平順的串流,但效能仍取決於底層裝置是快速的固態硬碟還是緩慢的網路磁碟,這差異有時會顯露出來。
你的程式呼叫 open("notes.txt") 與 read(fd, buf, 100)。它從不指明要抓哪顆磁碟的哪些磁區、要送什麼電壓、或固態硬碟在內部如何重新映射區塊。作業系統把這一個乾淨的讀取,轉成正確的、裝置專屬的指令,再把 100 個位元組交回給你的程式。
一個簡單的讀取呼叫,藏起了一整疊裝置專屬的機制。
抽象以一些尖峰效能換取簡潔與可攜性的巨大收益。多數程式樂意接受這筆交易;少數對效能極度敏感的程式則會去用更低階的介面(或繞過核心)以奪回失去的速度。