中斷簡述
核心的一個工作任務是管理週邊的硬體設備,不過由於核心處理器的科技進步發展,現在的處理器通常速度都比週邊快上好幾個量級,對於一些很慢的週邊,核心發出請求之後不應該空等它的回應,等它真的完成工作之後再回來處理相關的事宜。為了達成這個目的,其中一個做法是「輪詢 (polling)」的方式,來回一個週期的檢查週邊的狀態並加以反應。但是這樣做其實很花力氣,無論週邊有沒有完成任務,核心都還要花力氣去檢查。如果可以,讓週邊主動通知核心介入的時機,核心在其它的時間完全不用花力氣去理會,顯然比上述的做法要好上很多,我們稱之為「中斷(interrupts)」。
舉例來說,當你打字的時候,鍵盤控制器會發出中斷提醒作業系統要注意:有按鍵被按下了。這些電氣訊號就是中斷訊號。收到迅號後,處理器會通知作業系統處理新進的資料,週邊相對於處理器會以非同步的方式產生中斷,意即中斷可以在任何時間點發生。因此如要在中斷發生時能立即加以處理,核心也需要能隨時被打斷才可以。
每個週邊會連結到特定的中斷,而每個中斷會對應到一個特定的數值。作業系統得以藉此判斷訊號是由哪個硬體裝置所發出,進而採用不同的應用程式來加以處理。這些數值,如同電話號碼一般,代表的是不同的線路,所以又被稱作「中斷要求線路的週邊裝置(interrupt request lines),或簡稱為 IRQ lines。像 PC 上的計時器使用的中斷就是 IRQ 0 ,而 IRQ 1 通常會是由鍵盤所使用。
中斷處理程式
核心裡面用來處理特定中斷的函式叫做「中斷處理程式 (interrupt handler)」或「中斷服務例行常式」 (interrupt service routine 簡稱做 ISR )。每個產生中斷的週邊都會跟一個中斷處理程式相連。舉例來說,核心中可能會有甲函式專責處理系統計時器的中斷,而乙函式則負責處理鍵盤所產生的訊號。其實,對於週邊來說,中斷處理程式就是「驅動程式」的一部份,放在核心當中,負責管理該項硬體。
中斷處理程式一般都是 C 函式來處理,為了讓核心可以用一致的方式來傳遞資訊,這類函式的介面必須符合特定的原型(prototype),除此之外,寫法跟一般的函式沒有什麼兩樣。與其它的函式不同的地方在於中斷發生的時候,核心會用中斷處理程式回應週邊的請求,同時,他們的執行環境很特別,叫做中斷執行環境(interrupt context),簡稱做中斷環境,這一點晚點再來做詳細的介紹。
因為中斷隨時都會發生,所以中斷處理程式會隨時執行,為了能盡快的讓被打斷的程式回工作,迅速地完成處理是一件很重要的事情。所以雖然週邊硬體會希望它的中斷要求能盡快得到滿足,但是對系統其它的部份來說,被打斷的時間要越短越好。在極簡單的情況下,中斷處理程式只需要回應硬體,我得到你的通知了,這樣就可以讓硬體回去工作。但大多的情況下並不是這樣,中斷程式往往還有很多事情要做。舉網路裝置的中斷處理程式為例:除了回應硬體之外,處理程式還得把封包由網路硬體複製到系統主記憶體上面,稍加處理之後,再把資料傳給合適的協層 (protocol stack) 或應用程式。顯然,這是很麻煩的工作。(尤其在網卡資料量愈來愈多的現代高速網卡)