系統篇
內核
應用和底層硬件(CPU、內存、硬盤等)的連接橋梁。
用戶態和內核態
CPU和進程可以在兩種態下運行。
內核態可以直接訪問所有硬件資源,用戶態需要通過“系統調用”陷入到內核態才能否則只能訪問用戶空間地址的內存(虛擬內存)。
什么時候能從用戶態陷入到內核態
就兩字——中斷!
中斷可能是由于系統調用(用戶態主動陷入)、異常(缺頁、除0)、外設中斷(硬盤讀寫完成等)三種情況產生。
什么是系統調用
程序需要訪問硬件資源時候,例如內存、硬盤、網卡,就會“系統調用”陷入內核。
一次系統調用會發生兩次CPU上下文切換(CPU上下文指的是CPU寄存器和程序計數器)
第一次是從用戶態切換到內核態,寄存器原來是用戶態的指令位置需要先保存起來,然后更新成內核態指令的位置,最后跳轉去內核態執行任務。
第二次是內核態切換回用戶態,寄存器恢復為用戶態的指令位置,回到用戶態運行進程。
用戶態和內核態是如何切換的
每個進程都有兩個棧,用戶棧和內核棧。運行在哪個態就會使用哪個棧。
態的切換最重要的就是棧的切換!
實際上就是把用戶態的一些寄存器值壓入到內核態棧,從內核態返回時彈棧。
什么是中斷?為什么要有中斷(外設中斷)
這是系統用來相應硬件設備請求的一種機制,會打斷正在執行的進程,然后調用內核中的中斷處理程序來響應請求。這是一種異步的處理事件的機制,可以提高系統的并發能力。
那為什么要有這個中斷,舉個例子,點了個外賣,沒有中斷(外賣員給你打電話)的話,你就得一直盯著(同步)或者隔三岔五(CPU輪詢)看一眼外賣進度,這太耽誤事了。有中斷(外賣員到了打電話),你就可以心安理得干別的事情,等外賣來了你再停下去處理外賣。
什么是硬件中斷和軟件中斷
Intel的CPU提供了三種中斷程序執行的機制,分別是:
- 中斷(interrupt):點了下鼠標、敲了下鍵盤,這屬于異步事件
- 異常(exception):CPU執行指令時發現了錯誤,比如除0、缺頁,這屬于同步事件
- INT指令:INT指令后面跟了一個數字,相當于直接告訴CPU中斷號。Linux用的是INT 0x80
前兩者屬于硬件中斷,因為是硬件(外設或者CPU)自動觸發的
INT指令屬于軟件中斷,是程序觸發的
什么是硬中斷和軟中斷
由CPU硬件實現的中斷機制是硬中斷,中斷、異常、INT指令都是CPU實現的中斷機制
由軟件實現的中斷機制是軟中斷,比如Linux實現的軟中斷守護進程
二者效果相同都是中斷當前程序而去執行中斷處理程序,處理完返回執行原程序
為什么要有軟中斷
主要就是讓硬中斷盡可能簡單,提高系統響應速度。
比如網卡接受處理數據包這種會比較慢,而硬中斷資源很寶貴,占著不放會影響別的硬中斷相應(比如鼠標卡了)。而且中斷處理程序相應中斷時候,可能會臨時關閉中斷,意味著一個中斷沒處理完,別的中斷都不能被處理。這不行!!!
所以Linux將中斷分為上下兩部分
- 上半部分用來快速處理和硬件緊密相關或者時間敏感的時期
- 下半部分用來延遲處理上半部分未完成的工作,一般由內核守護進程完成。就是解耦了,異步處理。這一部分是通過對軟中斷標記數組的某一個位置做一個標記,然后內核守護進程會輪詢看數組哪個位置被標記為1了。按照標記位去找對應的處理程序。