第一部分、內務子系統
操
作系統核心的管理功能以及執行最終也要歸於cpu的執行流,因此最簡單的設計就是將核心的內務也設計成進程,但是對於一些特別的內務這個辦法就不適用了,因為這些內務的特殊性恰恰在於它們是依賴cpu的,或者說是和cpu進行介面的。如果我們把電腦視為一台人類發明的智能的機器,那麼很自然的,類似上帝造人那樣,我們會把電腦設計成人的模樣,電腦應該有心跳和反射。
到底什麼是核心的內務
呢?其實舉個例子就明白了。餐廳是顧客吃飯的地方,然而餐廳服務員也是人,也要吃飯,他們的吃飯問題就是內務問題,另外,餐廳需要及時打掃保持衛生,餐廳打掃衛生的阿姨的工作也屬於內務問題。重要的問題是內務事務應該怎樣執行。餐廳工作人員吃飯是直接付費還是免費還是從薪水中扣除...
內務子系統包括作業系統所有的子系統(進程、檔案、記憶體...)加上中斷等內容
一、時鐘
1、時鐘是最底層也是最基本的磁碟機。
時
鐘提供了基本的脈搏。
正
如動物的心跳一樣,時鐘提供了一切的節拍。
整
個機器依靠時鐘的驅動運行。cpu晶片被精確設計,在周期性的時鐘邊緣觸發事件中推進執行邏輯的值,比如EIP寄存器。然而cpu認為系統只有一個進程,一個執行流,這是馮.諾依曼機器模型決定的。
操
作系統必須擷取這個事件,然後執行作業系統相關的操作,比如進程調度等等。
2、中斷處理
如
果再次和動物心跳進行類比,那麼中斷就類似於反射(條件反射和非條件反射),當人被從背後拍打肩膀時,人會本能的扭頭,或者膝跳反射,這些都是明顯的例子。
操
作系統設定了中斷處理常式,當cpu檢測到中斷事件發生時,將執行流自動路由到時鐘中斷處理常式。設定中斷處理常式正如條件反射的學習過程一樣。
3、時鐘和中斷的關係
對
於會思考的動物,心跳和反射無疑在其生理和心理行為中扮演了兩大重要的角色,可以想象,沒有心跳和瞬時反射的植物雖然也是生物,然而卻幾乎只能進行細胞分裂而無法進行豐富的生理和心理活動。
對
於電腦而言,心跳和反射依然重要,然而不同於動物,電腦的心跳是反射的一部分,對於動物來講,心跳是心臟完成的,而反射是神經系統完成的。
時
鐘中斷也是一種中斷,心跳和反射統一於中斷。時鐘也是由一個中斷提供的。注意電腦和動物的區別,是否這一點導致了電腦不可能實現智能化?
神
經系統和心臟的分工是好的,心臟僅僅提供節拍和能量,而神經系統只提供行為。然而問題真的如此簡單嗎?
4、時鐘中斷處理-Linux
更
新當前進程的時間統計值
檢
查是否需要進行進程調度
如
果需要調度的話,進行進程調度。使更需要啟動並執行進程運行。
再
次重申,具體實現不重要,代碼不重要,因此此部分內容很少,看代碼就好...
二、非強制中斷機制
1、硬體中斷機制
外
設有事件的時候,會發起硬體中斷,硬體中斷處理常式需要做的工作量很不統一。
硬
件中斷處理常式必須需要很快完成。中斷是一種異常執行流,它不應該過分的影響正常執行流。比如一家人其樂融融,突然被一個不速之客(比如送快遞的或者送牛奶的)打斷了快樂,此時,不速之客最好的辦法就是辦完事趕快離開,或者在不能快速幹完事的情況下,告知主人重要事宜後離開,主人待到快樂過後自行處理...
L
inux在硬體中斷處理常式中觸發一種稱為softirq的非強制中斷。
2、非強制中斷
耗
時比較久的中斷處理事務
三、核心線程和工作隊列
L
inux將核心的一些事務交給核心線程來做。
任
何驅動程式或者核心子系統在任何時候都可以提交一些任務讓核心來執行,這些任務全部交給工作隊列是合理的。
2.6
核心中引入了工作隊列,實際上工作隊列也是一種核心線程。在經過了多次瘦身之後,2.6.36之後將工作隊列進行了徹底的改進,使用者(核心子系統或者驅動等)僅僅提交任務,具體如何調度這些任務全部由核心來完成,剝奪了任務提交者的很多權力,比如驅動只能提交任務,而不能建立過多的核心線程。
第二部分、內務子系統和Linux各子系統的協調
四、Linux進程的執行
1、被fork,建立一個task_struct
2、exec一個新的磁碟映像,填充進程地址空間
一
般的,Linux的可執行映像是ELF檔案,該檔案的內容被載入新進程的地址空間
3、執行系統調用,比如read。
該
步驟使用了作業系統核心中的VFS子系統,如果保證進程永遠不使用檔案,那麼VFS完全可以從核心中移除。
4、被中斷
L
inux進程在執行過程中會經常被外設中斷,即使沒有任何外設,也會有時鐘中斷。被中斷之後,執行中斷策略,見前述。
5、執行期間需要大量記憶體
調
用mmap在進程地址空間申請虛擬記憶體,使用時通過alloc_pages申請物理頁面。
如
果系統再也沒有足夠的可用物理頁面了,將調用相關核心線程來釋放一些物理頁面,將之分配給當前需要頁面的進程。
Linux的內務子系統採用“盡量滿足”的策略,因為Linux的內務子系統的首要任務是為瞭解決有限的系統資源和潛在的、未知的、無限的進程需求之間的矛盾,因此核心決不能使用“怕堵車就不讓人買車”的策略,既然linux內務子系統是“服務性”的,它就要盡量滿足進程的需求,只有在實在滿足不了的情況下,才會返回一個錯誤,告知使用者沒有可以使用的記憶體了,這是合理的,起碼,內務子系統沒有什麼私心。
Linux的OOM-Killer存在很大的問題,問題就出在策略上,核心不能簡單的將佔用記憶體最多的進程kill掉,比如說一個重要的服務佔據可300M的記憶體,夠大了,然而一個惡意的程式僅佔3M的記憶體,可是它fork出1000個子進程...接下來咋辦?Linux記憶體子系統應該想辦法探測到這個事情嗎?如果這麼做了,勢必引起設計惡化的惡化,因為策略和機制耦合了,按道理來講,機制應該不理解策略的...
6、執行完畢,調用exit系統調用退出
Game over
,我呀,也該睡覺啦。今天是五一,工作時間,工作時間,時間,時間,時間...