作業系統極簡入門
- 2019 年 10 月 4 日
- 筆記
△向上生長, TO BE TO UP. 程式設計師成長充電站△
轉載請聯繫授權(微信ID:qianpangzi0206)
閱讀本文大概需要 11 分鐘
01
"作業系統"誕生
1940,1950 年代的電腦,每次只能運行一個程式,程式設計師在打孔紙卡上寫程式,然後拿到一個電腦房間, 交給操作員。等電腦空下來了,操作員會把程式放入,然後運行,輸出結果,停機。以前電腦慢,這種手動做法可以接受,運行一個程式通常要幾小時,幾天甚至幾周。但上節說過,電腦越來越快,越來越快,指數級增長。
很快,放程式的時間 比程式運行時間還長,我們需要一種方式 讓電腦自動運作,於是"作業系統"誕生了。
作業系統,簡稱 OS,其實也是程式,但它有操作硬體的特殊許可權,可以運行和管理其它程式。作業系統一般是開機第一個啟動的程式,其他所有程式都由作業系統啟動。
02
"作業系統"發展
作業系統開始於 1950 年代那時電腦開始變得更強大更流行。第一個作業系統加強了程式載入方式,之前只能一次給一個程式,現在可以一次多個。當電腦運行完一個程式,會自動運行下一個程式,這樣就不會浪費時間,找下一個程式的紙卡,這叫批處理。
電腦變得更快更便宜,開始在出現在世界各地,特別是大學和政府辦公室。很快,人們開始分享軟體,但有一個問題,在哈佛1號和 ENIAC 那個時代,計算都是一次性的,程式設計師只需要給那"一台"機器寫程式碼,處理器,讀卡器,印表機都是已知的。但隨著電腦越來越普遍,電腦配置並不總是相同的,比如電腦可能有相同 CPU,但不同的印表機。這對程式設計師很痛苦。
不僅要擔心寫程式,還要擔心程式怎麼和不同型號印表機交互,以及電腦連著的其他設備,這些統稱"外部設備"。和早期的外部設備交互,是非常底層的,程式設計師要了解設備的硬體細節。加重問題的是,程式設計師很少能拿到所有型號的設備來測程式碼,所以一般是閱讀手冊來寫程式碼,祈禱能正常運行。現在是"即插即用",以前是"祈禱能用"。
這很糟糕,所以為了程式設計師寫軟體更容易,作業系統充當軟體和硬體之間的媒介,更具體地說,作業系統提供 API 來抽象硬體,叫"設備驅動程式"。程式設計師可以用標準化機制和輸入輸出硬體(I/O)交互。比如,程式設計師只需調用 print(highscore),作業系統會處理輸到紙上的具體細節。
到 1950 年代尾聲,電腦已經非常快了,處理器經常閑著,等待慢的機械設備(比如印表機和讀卡器)程式阻塞在 I/O 上,而昂貴的處理器則在度假,就是放鬆啥也不做。50年代後期,英國曼徹斯特大學 開始研發世界上第一台超級電腦—Atlas,他們知道機器會超級快,所以需要一種方式來最大限度的利用它。
他們的解決方案是一個程式叫 Atlas Supervisor於1962年完成。這個作業系統不僅像更早期的批處理系統那樣,能自動載入程式,還能在單個 CPU 上同時運行幾個程式,它通過調度來做到這一點。假設 Atlas 上有一個遊戲在運行,並且我們調用一個函數 print(highscore),它讓 Atlas 列印一個叫 highscore 的變數值,讓朋友知道我是最高分冠軍。print 函數運行需要一點時間,大概上千個時鐘周期,但因為印表機比 CPU 慢,與其等著它完成操作,Atlas 會把程式休眠,運行另一個程式,最終, 印表機會告訴 Atlas, 列印已完成。
Atlas 會把程式標記成可繼續運行,之後在某時刻會安排給 CPU 運行,並繼續 print 語句之後的下一行程式碼,這樣, Atlas 可以在 CPU 上運行一個程式,同時另一個程式在列印數據,同時另一個程式讀數據。Atlas 的工程師做的還要多,配了4台紙帶讀取器,4台紙帶打孔機,多達8個磁帶驅動器,使多個程式可以同時運行,在單個 CPU 上共享時間,作業系統的這種能力叫"多任務處理"。
03
記憶體虛擬化
同時運行多個程式有個問題,每個程式都會佔一些記憶體當切換到另一個程式時,我們不能丟失數據,解決辦法是給每個程式分配專屬記憶體塊。舉個例子,假設電腦一共有 10000 個記憶體位置,程式 A 分配到記憶體地址 0 到 999,而程式 B 分配到記憶體地址 1000 到 1999,以此類推。如果一個程式請求更多記憶體,作業系統會決定是否同意,如果一個程式請求更多記憶體,作業系統會決定是否同意,如果同意,分配哪些記憶體塊。這種靈活性很好,但帶來一個奇怪的後果,程式 A 可能會分配到非連續的記憶體塊,比如記憶體地址 0 到 999,以及 2000 到 2999。
這只是個簡單例子,真正的程式可能會分配到記憶體中數十個地方,你可能想到了,這對程式設計師來說很難跟蹤。也許記憶體里有一長串銷售額,每天下班後要算銷售總額,但列表存在一堆不連續的記憶體塊里。為了隱藏這種複雜性,作業系統會把記憶體地址進行 "虛擬化",這叫 "虛擬記憶體"。程式可以假定記憶體總是從地址0開始,簡單又一致,而實際物理位置被作業系統隱藏和抽象了,一層新的抽象。
04
動態記憶體分配
用程式 B 來舉例它被分配了記憶體地址 1000 到 1999,對程式 B 而言,它看到的地址是 0 到 999,作業系統會自動處理虛擬記憶體和物理記憶體之間的映射。如果程式 B 要地址 42,實際上是物理地址 1042。
這種記憶體地址的虛擬化 對程式 A 甚至更有用。在例子中,A 被分配了兩塊隔開的記憶體,程式 A 不知道這點,以 A 的視角,它有 2000 個連續地址,當程式 A 讀記憶體地址 999 時,會剛好映射到物理記憶體地址 999,但如果程式 A 讀下一個地址 1000,會映射到物理地址 2000。這種機制使程式的記憶體大小可以靈活增減叫"動態記憶體分配"
05
記憶體保護
對程式來說,記憶體看起來是連續的,它簡化了一切,為作業系統同時運行多個程式,提供了極大的靈活性。 給程式分配專用的記憶體範圍,另一個好處是 這樣隔離起來會更好,如果一個程式出錯,開始寫亂七八糟的數據,它只能搗亂自己的記憶體,不會影響到其它程式,這叫 "記憶體保護"。
防止惡意軟體(如病毒)也很有用。
例如,我們不希望其他程式有能力,讀或改郵件程式的記憶體。如果有這種許可權惡意軟體可能以你的名義發郵件,甚至竊取個人資訊,一點都不好。
Atlas 既有"虛擬記憶體"也有"記憶體保護",是第一台支援這些功能的電腦和作業系統!
06
多個用戶用"終端"來訪問電腦
到 1970 年代,電腦足夠快且便宜,大學會買電腦讓學生用,電腦不僅能同時運行多個程式,還能讓多用戶能同時訪問,多個用戶用"終端"來訪問電腦。"終端"只是鍵盤+螢幕,連到主電腦終端本身沒有處理能力。
冰箱大小的電腦可能有50個終端,能讓50個用戶使用,這時作業系統不但要處理多個程式,還要處理多個用戶,為了確保其中一個人 不會佔滿電腦資源,開發了分時作業系統。意思是 每個用戶只能用一小部分處理器,記憶體等。
因為電腦很快,即使拿到 1/50 的資源也足以完成許多任務,早期分時作業系統中,最有影響力的是Multics(多任務資訊與計算系統),於 1969 年發布。
Multics 是第一個,從設計時就考慮到安全的作業系統,開發人員不希望惡意用戶 訪問不該訪問的數據。比如學生假裝成教授,訪問期末考試的文件,這導致 Multics 的複雜度超過當時的平均水準,作業系統會佔大約 1 Mb 記憶體,這在當時很多!可能是記憶體的一半,只拿來運行作業系統。
Multics 的研究人員之一 Dennis Ritchie 曾說過,"阻礙 Multics 獲得商業成功的一個明顯問題是從某種方面來說,它被過度設計了,功能太多了"。
07
Unix
所以 Dennis 和另一個 Multics 研究員Ken Thompson 聯手打造新的作業系統叫 Unix。他們想把作業系統分成兩部分:
1.首先是作業系統的核心功能,如記憶體管理,多任務和輸入/輸出處理這叫"內核"。
2.第二部分是一堆有用的工具,但它們不是內核的一部分(比如程式和運行庫)。
緊湊的內核意味著功能沒有那麼全面,Multics 的另一個開發者 Tom Van Vleck 回憶說:"我對 Dennis 說,我在 Multics 寫的一半程式碼都是錯誤恢復程式碼",他說:"Unix 不會有這些東西,如果有錯誤發生,我們就讓內核"恐慌"(panic),當調用它時,機器會崩潰,你得在走廊里大喊,"嘿,重啟電腦"。
你可能聽過 "內核恐慌"(kernel panic),這就是這個詞的來源,內核如果崩潰,沒有辦法恢復,所以調用一個叫"恐慌"(panic)的函數。起初只是列印"恐慌"一詞,然後無限循環。這種簡單性意味著 Unix 可以在更便宜更多的硬體上運行。使 Unix 在 Dennis 和 Ken 工作的貝爾實驗室大受歡迎,越來越多開發人員用 Unix 寫程式和運行程式。工具數量日益增長。
1971 年發布後不久,就有人寫了不同程式語言的編譯器甚至文字處理器,使得 Unix 迅速成為1970~80年代最流行的作業系統之一。
08
個人電腦
到 1980 年代早期,電腦的價格降到普通人買得起這些叫"個人電腦"或"家庭電腦"。這些電腦比大型主機簡單得多 主機一般在大學,公司和政府,因此作業系統也得簡單。
舉例,微軟的磁碟作業系統(MS-DOS)只有 160 kB一張磁碟就可以容納,於 1981 年發布,成為早期家用電腦最受歡迎的作業系統,雖然缺少"多任務"和"保護記憶體"這樣功能,意味著程式經常使系統崩潰。雖然很討厭但還可以接受,因為用戶可以重啟。
哪怕是微軟 1985 年發布的早期 Windows雖然在 90 年代很流行,但卻缺乏"記憶體保護",當程式行為不當時,就會"藍屏",代表程式崩潰的非常嚴重,把系統也帶崩潰了。幸運的是,新版Windows有更好的保護,不會經常崩潰。
如今的電腦 有現代作業系統比如 Mac OS X,Windows 10,Linux,iOS和Android,雖然大部分設備只有一個人使用。作業系統依然有"多任務, "虛擬記憶體", "記憶體保護",因此可以同時運行多個程式:一邊在瀏覽器看 YouTube,一邊在 Photoshop 修圖,用 Spotify 放音樂,同步 Dropbox。
如果沒有作業系統這幾十年的發展,這些都不可能,當然,我們也需要地方放程式,我們將在下一節講。
相關閱讀:
- 電腦晶片的發展
- 演算法入門