第 06 章 - 計算機概論 - 作業系統概論
上次更新日期 2020/02/10
每一台主機上面大致上都要安裝一個作業系統。那為何需要作業系統?他與硬體的關係?應用程式的關係是怎樣? 作業系統與記憶體的關係是怎樣?多元程式處理系統是什麼?在記憶體中的工作 (job) 該如何被 CPU 所執行? 什麼是中斷 (interrupts) 等等,都大致了解一下!這一章大致上都以口述為主,花費的時間應該會比較短!
學習目標
- 認識批次作業系統、多元程式處理系統
- 認識硬體、核心 (kernel)、系統呼叫、應用程式與使用者的相關性
- 了解記憶體中各個程序的狀態大致有哪些
- 認識作業系統的基本元件與功能
- CPU 的設計是提高時脈還是多顆 CPU 核心(cores)
6.1: 電腦硬體概說
為何需要了解硬體?這是因為我們的軟體是架構在硬體上面進行開發的!硬體沒有的功能,軟體當然無法在上面進行運作! 所以,先來了解一下硬體的演化史~大家才會知道,為何目前我們的系統是以這樣的方式來進行運作的。
計算機硬體歷史可以回朔到 1800 年代,不過當時的電腦並不是使用電力的,而是機械式的操作。後來到了 1930 年代後,才漸漸開發出以電力提供的計算機硬體。 詳細的計算機硬體可以從底下的連結去查閱比較細節的部份。
- 第一時期:1642~1946
主要是透過機械設備來進行四則運算 (加減乘除)。例如法國人的 Pascalene 加法器以及德國數學家設計的 Stepped Reckoner 計數器。 後來進入 1833 年,英國數學家巴貝奇設計出差分機等。
- https://en.wikipedia.org/wiki/Pascal%27s_calculator
- https://en.wikipedia.org/wiki/Stepped_reckoner
- https://zh.wikipedia.org/wiki/差分機
不過上述的設備大部份都還是需要手動來操作計算器,尚未有『程式撰寫』與『機器本體』分開的概念,直到卡片設計出現之後!
- 卡片的使用:1800 年代
同學們在台灣各種大考時,總是會有填寫答案卡的時候,如下所示。你可能會問,那麼為什麼要使用畫卡的方式來作答呢? 這當然是為了要預防人眼睛的誤判!而改用光學的方法,根據答案紙塗寫的感光資料,進行答案的確定,以更快速的方法來取得作答者的成績。 因此答案卡得要搭配光學讀卡機的判讀,來取得同學卡片上面的成績,讀卡機也如下所示:
(圖片來源請參考:https://slidesplayer.com/slide/11237318/)
(圖片來源請參考:http://www.sekonicmp.co/slide/sr-430-product-index/)
為何要用卡片呢?最早期的卡片是為了織布機所設計的,織布機可以透過卡片上面的孔洞,來產生不同的花樣。這跟計算機有什麼關係? 基本上,此時織布機的硬體不需要重新設計或修改,只要修改卡片上面的孔洞,花樣就可以不一樣。這個『織布機』就是電腦硬體的概念, 這個『卡片』就是程式碼的概念!所以,這件事情相當重要!
後來赫爾曼何樂禮 (Herman Hollerith) 在 1890 年代開發一種排序機器,可以透過打孔卡片儲存資料,再透過機器感應卡片的孔洞, 得以快速讀取資料,後來何樂禮在 1896 年成立製表機器公司,並在後來成為 IBM 公司的一部分。直到 1970 年代為止,很多電腦設備還是以卡片作為程式碼的撰寫, 透過讀卡機將程式碼載入電腦中運作!
- 第二時期:1946~1954
包括打孔卡的原理,大部分都是以 0 與 1 來進行程式的設計。因此,在電力逐漸普及之後,人們開始來思考,能不能用電力來處理 0 與 1 的輸入, 後來得到的答案,就是透過真空管來進行這個設計!為了讓真空管裡面的電子流動可以順利進行,避免被空氣所干擾,整個管子需要抽真空, 因此就被稱為是真空管了!
開始透過真空管作為主要元件來進行電腦的設計,包括美國軍事機構為了計算彈道射程而開發的 ENIAC (重量達 30 公噸,含 1.8 萬隻真空管,耗電 15 萬瓦的電力操作), 英國劍橋大學的 EDSAC 系統,以及 UNIVAC-1 商用電腦系統等。此時電腦還沒有鍵盤輸入資料,而是透過讀卡紙打洞之後,讓系統讀入,然後輸出透過印表機來輸出。 如果有個動作錯誤,就需要全部重來一遍。
- https://zh.wikipedia.org/wiki/電子數值積分計算機
- https://zh.wikipedia.org/wiki/延遲存儲電子自動計算器
- https://en.wikipedia.org/wiki/UNIVAC_I
- https://zh.wikipedia.org/wiki/馬克一號
- https://en.wikipedia.org/wiki/Punched_card打孔紙
不過真空管體積很大,又容易因為飛蛾小蟲子在冬天暖暖的附著在上面,導致真空管的破損,而造成計算失敗。因此,後來除了在某些音響設備上面還保持之外, 大部分都被淘汰了。( debug 的由來啊!)
- 第三時期:1954~1964
貝爾實驗室在 1947 年開發出電晶體 (Transistor) 之後,真空管就被這玩意兒取代了。包括貝爾實驗室內部的 TRADIC 系統等等。
- 第四時期:1964~1970
在真空管之後開發出積體電路 (Integrated Circuit, IC),後來積體電路被拿來取代電晶體,讓電腦的體積大大降低。1964 年 IBM 開發出相當熱門的 system/360 系統即是一例。
- https://zh.wikipedia.org/wiki/IBM_System/360,建議看英文版,會有更多的圖解。
- 個人電腦時代
1972 年開始 Intel 開發出多款的微處理器,包括 8008, 8080, 8086 等,尤其自 8086 之後,就是第一款的 x86 個人電腦設計架構。之後的個人電腦統稱為 x86 架構的原因在此。
6.2: 早期的作業系統類型
電腦軟體當然是跟著硬體來跑的,因此不同的硬體系統就會有不一樣的作業系統產生。最早之前的電腦硬體,因為每部硬體的設計不同, 因此每次要執行程式時,程式設計師都得要自行參考電腦硬體來設計出運算的軟體,當時的系統並沒有『作業系統』的概念,因為應用程式與作業系統是同時設計的。
- 批次系統
但是因為每次要執行該程式都會很困擾,使用者得要排隊去讓系統讀卡操作。因此後來開始有了『批次系統』的設計。因為電腦裡面有儲存設備 (不論是硬碟還是記憶體), 所以電腦硬體裡面會執行一隻監督程式 (monitor),使用者可以預先將自己的程式讀進系統,系統先儲存該程式到佇列 (queue),等到輪到該程式運作後, 就將該程式讀入讓 CPU 開始運作,直到運作結束輸出到印表機之後,將該工作丟棄,然後開始讀入在 queue 裡面的新的程式,依序執行。
不過這樣的架構底下,我們可以發現到程式的進行常常卡在讀卡與印表機上面。因此後來監督程式可以自行判斷該工作是否在列印, 若在列印了,就將該工作丟到另一個子系統去輸出,而不再管理。然後直接讀出下一個程式來運作,以加快系統運作的效能。將 CPU 與 I/O 分離開! 這樣的效率就會好多了。
這個時候,人們還是不能跟作業系統互動的,大部分還是透過卡片與讀卡機,將程式碼一次性的讀進大機器,然後就是等待大機器的運作, 結果再交由印表機印出。如果打卡紙打洞錯誤呢?只好重新打洞,重新排隊去運作程式了。
- 多元程式處理系統
這種架構是在記憶體比較大之後才開發出來,系統允許兩個以上的程序在記憶體中等待被 CPU 執行,當 CPU 執行完其中一隻程式後, 第二隻程式就可以立刻被執行,因此效能會比較好。此外,當系統進入 I/O (例如列印) 情況下,該程序就會被中斷 (Interrupt) ,但這個中斷並不是停止的意思, 而是『程序的狀態進入中斷狀態,CPU 不會理會該程序』的意思。
基本上在記憶體當中的程序有底下三種基本的狀態:
- 執行 (running):該程序正被 CPU 運作當中
- 預備 (Ready):該程序排在佇列當中,等待 CPU 的運作
- 等待或中斷 (wait/interrupt):該程序需要在 I/O 的情況下,此時 CPU 不會理會該程序。
這種系統最重要的設計在於 CPU 的排程 (cpu scheduling),包括是否有最優先需要運作完畢的程序?每支程序最多能夠運作多少時間等, 都是需要考量的。另外,讀者須知道早期單核 CPU 的運作中,CPU 一次只能運作一個工作,因此,若有多個工作要同時進行, 那麼 CPU 就得要安排一個 CPU 運作時間給所有的工作,當該程序達到最大工作時間後,CPU 就會將該工作排回佇列,讓下一隻程序接著運作。 由於 CPU 的速度太快,因此你會覺得 CPU 是同時運作所有的程序,其實不是的!而是 CPU 在各個程序之間切換工作而已。
不過,這個時候使用者依舊無法與系統互動喔!
- 分時系統
前兩個系統通常沒有安排使用者操作界面,亦即所有的程序都是監督程式在進行的,使用者只能將工作丟進系統而已,並不能即時的操作控制。 後來分時系統 (Time-Sharing system) 就被提出來使用。所謂的分時系統其實與多元程式處理系統有點類似, 只是工作的輸入改為透過終端機操作輸入,CPU 可以在各個用戶操作間切換工作,於是每個使用者感覺似乎都是在同步操作電腦系統一般, 這就是分時系統。
之所以要繪製多元程式處理系統,是因為目前的許多概念都是從這個系統來的,尤其是在記憶體當中的程序狀態,更是重要!
6.3: 作業系統概念
想一想,如果你要使用簡易型計算機去計算加減乘除時,你是怎麼做的?不就是將你要計算的算式用計算機的數字鍵盤打字後,看看螢幕上面的算式正確否, 若是正確,就按下等於的符號,螢幕上就會出現正確的數值了。所以,你只要輸入算式即可。早期的程式設計師沒有這麼好用的東西~ 如果要計算加減乘除,還是得要自己處理計算機內部的運作!
也就是說,早期的程式設計師要設計程式是件苦差事,因為得要了解電腦硬體,並根據該電腦硬體來選擇程式語言,然後根據程式語言來設計運算工作、記憶體讀寫工作、 磁碟與影像輸入輸出工作、檔案存取工作等。等於從硬體、軟體、輸入輸出行為都得要在自己的程式碼裡面一口氣完成才行。但是所有的電腦硬體都有點不太一樣, 所以,只要換一台電腦硬體,全部的程式碼就得要重新改寫,運作上面非常沒有效率。
後來在 1971 年開始的 unix 系統開發後,後續的系統大多使用 unix 的概念,整體系統的運作拆成兩部份來處理:
- 將硬體管理的工作統一交給一組程式碼去進行,而且這組程式碼還提供了一個開發界面
- 軟體工程師只要依據這組程式碼規範的開發界面後,該軟體開發完成就能夠在這組程式碼上面運作了!
上面第一個部份提到的這組程式碼加上那個開發界面就是一個作業系統 (operating system, OS) 了。 如下圖所示,作業系統指的是核心與系統呼叫 (系統呼叫就是剛剛提到的那個統一的開發界面),使用者則是主要操作應用程式 (軟體) 而已。 而軟體設計師 (程式設計師) 就不須要重新設計驅動硬體的種種動作,直接考慮應用程式的撰寫即可 (就像在計算機上面思考你的算式即可)。
那麼這個核心 (kernel) 除了管理硬體 (CPU/RAM/DISK...) 之外,還需要進行什麼事情呢?從多元程式處理系統裡面,我們知道程序需要放在記憶體當中, 而 CPU 的工作排程也是很需要設計的,另外,磁碟的讀寫效能,以及相關的檔案系統,還有網路功能,全部都是作業系統應該要提供的主要元件!作業系統的基本元件功能大概有:
- 程式的執行:
作業系統除了管理硬體之外,最重要的就是將使用者交付的任務 (程式) 執行完畢。因此,作業系統需要將使用者交付的軟體程序分配到記憶體中, 然後透過 CPU 排程持續的交錯的完成各項任務才行。 - CPU 中斷 (interrupt) 的功能:
如同多元程式處理系統談到的,程序的狀態可能會進入所謂的中斷階段。在現在的作業系統中,CPU 根據硬體擁有許多與週邊硬體的中斷通道, 當接收到中斷訊號時,CPU 就會嘗試將該程序列入等待的狀態下,讓該硬體自行完成相關的任務後,然後再接管系統。不像以前舊式的環境, CPU 得要持續不斷的去偵測該動作是否完成。 - 記憶體管理模組:
舊的環境底下,程式設計師需要自己判斷自己的程式會用到多少記憶體,然後自行指定記憶體使用位址的任務。現代作業系統會有記憶體管理模組, 該子系統會自動去偵測與管理主記憶體的使用狀態,避免同一個記憶體位址同時被兩個程序所使用而讓程序工作損毀。此外,由於作業系統核心也在記憶體中, 因此核心也會被這個子系統放入受保護的記憶體區段,一般用戶是無法直接操作該受保護的記憶區段的。 - 虛擬記憶體 (virtual memory):
當 CPU 要讀入程式或檔案資料時,總得從主記憶體當中讀入,但是,主記憶體當中的資料並不是連續的,主記憶體的資料就像磁碟一樣,重複讀、刪、寫之後, 記憶區段是不會連續的。但是為了強化效能,通常 CPU 要讀入程式,只會讀入該程式在記憶區段的開頭位址與長度而已。因此,現代作業系統有開發一個虛擬記憶體, 他會記憶程序是在主記憶體的哪個區段內,但是程序區段是連續的!所以 CPU 主要讀出虛擬記憶體,記憶體管理模組就會主動讀出資料了。例如下列的示意圖:
上圖指的是,一隻程序的資料是連續的 (左側),但是實際上對應的是在主記憶體或其他位置上。 - CPU 排程:
這是作業系統好不好的重要指標之一!如何讓 CPU 在多工的情況下以最快速的方式將所有的工作完成,這方面的演算法是目前各主要作業系統持續在進步的部份。 目前常見的是優先權多工技術 (Preemptive multitasking),我們知道 CPU 必須要在各個程序之間切換運作,但是哪些程序需要比較優先的等級運作, 哪些程序可以稍微慢點完成,這就是優先權多工的判斷工作。基本上,我們可以想成程序在多個佇列中排隊,有的佇列可以比較快被運作, 有的佇列則是比較晚被運作的意思。 - 磁碟存取與檔案系統:
通常使用系統讀寫檔案只要知道檔案位置哪裡就能夠讀寫與複製了。但是作業系統則需要驅動磁碟(不論是傳統硬碟還是 SSD),然後也需要了解該磁碟內的檔案系統格式, 之後透過檔案系統這個子系統來進行資料的處理。 - 裝置的驅動程式:
裝置的變化日新月異,所以作業系統必須要能夠接受硬體裝置的驅動,所以硬體製造商可以推出給各個不同作業系統使用的驅動程式 (dirver / modules), 這樣作業系統直接將該驅動程式載入後,即可開始使用該硬體,而不需要重新編譯作業系統。 - 網路子系統:
其實網路是作業系統提供的!因此才有所謂的『網路作業系統』的名詞。目前所有的現代作業系統都會支援 Internet,所以現代的作業系統都是網路作業系統。 - 使用者界面:
一個桌上型生產力軟體經常需要一個圖形話界面的支援,這也是作業系統應該要提供的界面選項。不過許多的伺服器就無須圖形界面,只要有文字界面即可。 圖形界面被稱為 graphical user interface (GUI),在一般桌上型應用是相當需要的。
也就是說,在四個圓形圖的畫面中,作業系統核心至少就要提供上述的功能與資源管理的任務,所以作業系統管的真的很多! 而且每個子系統內部都有很多重要的、可持續修改以發揮系統效能的部份。
6.4: CPU 的設計與作業系統
早期的系統,為了加快運算功能,因此都著重在 CPU 的指令集與時脈上面,尤其是時脈的增進!Intel 與 AMD 這兩家主要的個人電腦 CPU 製造商, 都以拉高 CPU 運算時脈來設計他們早期的 CPU 晶片。不過,這個有點限制,因為時脈越高,耗電量以及相關的運算會越快,可能產生的干擾會越大, 因此,很難將單一 CPU 的運算時脈拉到 5GHz 以上的地步。
- CPU 核心數量的設計與多處理器作業系統
由多元程式處理系統,我們知道,在多工 (多個不同的工作需要同時執行的情況) 的情況下,單一 CPU 需要在不同的工作間切換, 這也是現代作業系統需要處理的。這有兩種解決方式,一個是讓單一 CPU 更快速的運作,另一個...再加幾顆 CPU 進去,不就可以解決了? 是的,這也是現代 CPU 設計的主要思考依據,讓一個 CPU 封裝 (單一一顆 CPU 硬體) 裡面,整合多個 CPU 核心,也就是多核心 CPU 製造的思考方向。
當你的 CPU 數量越多,代表同一個時間可以工作的數量越多,當然你的執行效能就會比較高。但是對於單執行緒的程式來說, 多核心的 CPU 不見得會跑得比單核的快!這是因為單執行緒只有一個程序在進行,所以 CPU 時脈越高,代表會越快執行完畢。 但是對於多個工作的情況下,多核心 CPU 的效能當然會更高!現今很多的影音編輯軟體、轉檔軟體都會用到多執行緒, 也就是說,這些軟體會將單一工作拆分成數個小工作,分別交給不同的核心去執行,這樣每個核心只要負責一小段任務, 當然 CPU 時脈不用高,只要數量夠大,效能就會提昇很明顯!
由於 CPU 是由作業系統控制的,因此,你要使用到多核心的硬體系統,你的作業系統、應用程式都需要設計程可以支援多核心才行! 對於核心來說,當然一定要能驅動多個 CPU 核心,同時該核心也需要能夠將不同的 jobs 丟給個別的 CPU 去運作。而應用程式的撰寫上, 也需要能夠將單一 job 拆成數個小程序,才能夠讓個別 CPU 去運算喔!
- 分散式系統
多處理器系統裡面可能有多個程式,同時交付給不同的 CPU 去執行,或者是例如影音轉檔任務,將一個比較大的工作拆分成數個工作後, 分別交給個別的 CPU 去執行。不過,這種情況下,大部分的工作都是彼此無關的,因此每顆 CPU 都可以自行完成各自的工作, 無須回報給某個大程式。
對於數值模式來說,例如溫室效應的影響、全球暖化的問題研究、宇宙大爆炸的模型、數天到數周後的天氣模擬或空氣品質模擬等, 這些模式無法將第一天到第十天分成 10 個 jobs 丟給不同的 CPU 跑,因為每一天之間是有相關性的!你得跑完第一天,才能跑第二天! 所以無法像上面的多處理器作業系統一般,讓每個 CPU 獨立完成各自的小工作。
在這些數值模擬的行為下,我們就得要透過所謂的平行處理功能,讓一件工作可以拆分成數個部份,讓這些不同的部份丟給不同的 CPU 去運算, 然後再透過一支監控程式,將各別的計算在一定的時間內收回統整後,再次的細分小工作發派出去,持續這些動作後,直到程式執行完畢為止。
在這樣的情況下,你有兩種模組的硬體可以選,一種是透過類似 top500 的超級電腦來運作,但是...超級電腦不是一般人可以使用到的! 你也可以前往國家高速網路中心去租用一下這種超級電腦的使用:https://www.nchc.org.tw/Page?itemid=2&mid=4。
另一種比較便宜的方式,就是搭建多台多處理器的系統,然後透過網路,將這些系統連結,透過一些作業系統子系統功能的搭建, 組合成叢集電腦 (cluster),讓多個系統透過網路同時執行一項工作。
2020 年 AMD 發布了一顆 64 核心 128 執行緒的消費市場的 CPU,有了這一顆 CPU,很多小型的叢集電腦就可以不用搭建了! 畢竟在單一電腦或單一封裝內的資料運算速度,要比透過網路連線的速度快的多!甚至在比較高階的商用主機板上面,可以安插多顆 CPU, 當然啦,那種類的 CPU 就不是消費型市場的 CPU 設計囉!
- 單一作業系統支援的 CPU 數量
在個別的硬體上面都應該安裝作業系統,但是,不是所有的 CPU 核心都會被作業系統驅動喔!對於一般 Windows 10 來說, 可以驅動的 CPU 核心數量大概是 256 個這麼多。對於 Linux 來說,大部分都可以支援到 4096 個 CPU 核心數。 現在看到 x86 系統上面,單一 CPU 封裝的核心數量,大致上為 64 個核心數,而單片主機板上面,最多常見的是 4 顆 CPU 封裝, 基本上,兩大作業系統大致上都能驅動足夠的 CPU cores 囉!
- 知名的作業系統
作業系統的沿革可以參考底下的許多文件:
- https://en.wikipedia.org/wiki/Operating_system
- https://zh.wikipedia.org/wiki/Microsoft_Windows
- https://zh.wikipedia.org/wiki/IOS
- https://zh.wikipedia.org/wiki/Android
從上面第一個連結我們可以看到包括銀行商用大型主機 Unix 系統,後來的教學用 Minix 系統,目前很熱門的 Linux 系統,很多資安人員愛用的 FreeBSD 系統, 連蘋果的 Mac OS X 也都是從 1970 年代開發的 Unix 沿用而來!Unix 真的是很厲害。
目前常見的桌上型電腦上的作業系統, 大致上還是以 windows 以及 Linux 為主,其中 windows 為單一一家微軟公司所開發維護,目前 (2020) 最新的版本為 windows 10。Linux 主要指的是核心 (kernel), 並非加上應用程式~以 linux 核心為開發的作業系統廠商,我們稱為 Linux 開發套件商 (Linux distributions),就有非常多!目前常見的幾個主流版本, 包括 Red Hat Enterprise Linux (RHEL)、Debian、Ubuntu等等。
伺服器領域的作業系統,老品牌商業公司的大型主機,通常使用 Unix 系統,包括 HP-UX、AIX、Solaris 等等,自由軟體方面的伺服器架構, 則有 Linux、FreeBSD等。
在手機領域方面,這種小型設備的系統,目前主流有兩個,一個是架構在 Linux 核心開發的 Android 系統,一個是由蘋果電腦所開發的 IOS 系統。 其他還有很多的手機作業系統,不過以目前的市占率來說,這兩個大致上是主流。
6.5: 課後練習
作業上傳時的注意事項:
- 伺服器的詳細資料,以及相關傳輸軟體設定,請參考第一章的 1.5 節的內容。
- 可以使用 MS office 的 word 或者是 libreoffice 的 writer 等軟體來撰寫你的作業,作業檔名可以使用 .doc, .docx 或者是 .odt 或者是 pdf 等格式,均可接受。
- 若作業中有圖檔,請將圖檔降低水平解析度到 800 像素以下再貼到文章中,檔案容量以不超過 2Mbytes 為限。
- 檔名請設定為: os_4XXXCYYY_unit06.doc (4XXXCYYY 是你的學號,請填正確,有分大小寫,請確認)
- 請上傳到你家目錄底下的 os 目錄中 (若不存在,請自行建立該目錄)
開始本章節題目:
- 在 wiki 上面查詢 debug 的最原始原因為何?(註:與蟲子及真空管有關)
- 繪製出多元程式處理系統,注意每個圓圈的箭頭方向,並且說明基本的程序三種狀態。
- 以四個同心圓說明 (1)x86 個人電腦 (2)POSIX 標準 (3)browser (4)Linux kernel 之間的層層相關性。
- 找出目前 Linux kernel 的最新版本 (寫下你尋找的日期與該日期你查到的最新版本號碼)
- 著名的圍棋電腦深藍使用的作業系統為 AIX,請觀察 https://en.wikipedia.org/wiki/File:Unix_history-simple.svg 這個資料,認真的說明 (1)Linux (2)AIX 作業系統是從哪個系統延伸出來的?
- 用 100 個字以內的說明,解釋什麼是虛擬記憶體 (virtual memory) (用自己理解的想法寫下來,所以沒有標準答案)
- 在 Linux 系統中,哪些組合按鍵可以進入 tty3 呢?
- 在系統的運作過程中,什麼是 CPU bound 與 I/O bound