中斷的歷史原因
在聊中斷機制之前,我想先和大家聊一聊中斷機制出現(xiàn)的前因后果。最一開始計算機操作系統(tǒng)的設計是能夠一次性的執(zhí)行所有的計算任務的,這被稱為順序執(zhí)行,也是批處理操作系統(tǒng)(Batch system)。
順序執(zhí)行的意思是一個任務接著一個任務的依次執(zhí)行,就像我們編寫代碼的時候,我們肯定是寫完一行代碼才會寫下一行代碼,此時的計算機也是這樣的,執(zhí)行完一個任務后才會執(zhí)行下一個。就相當于 main 函數(shù)里面只有一個 while(1) ,永不停止。
這樣的操作系統(tǒng)是當時最高效的系統(tǒng),但是這種系統(tǒng)會存在兩個問題:
下一個任務只能在當前任務執(zhí)行完成后才得以執(zhí)行,拿上圖來說就是任務 A 執(zhí)行完成后才會執(zhí)行任務 B,任務 C 在任務 A 和任務 B 執(zhí)行完成后才會得到執(zhí)行,任務 D 同理。當任務執(zhí)行遇到問題或者出錯時,就直接修改當前任務的 PC 指針,將其指向下一個任務就完事了。
任務執(zhí)行的次序是單項的,就是只能以 A -> B -> C -> D 這樣的次序執(zhí)行,不能以 D -> C -> B -> A 這樣反向的順序執(zhí)行。
這樣的操作系統(tǒng)無疑是很簡陋的(或者此時不應該稱之為操作系統(tǒng),實際上就是一個監(jiān)控系統(tǒng))。
隨著時代的發(fā)展,后來出現(xiàn)了很多計算機,不過此時計算機還沒有改變依次執(zhí)行順序,當計算機在做 IO 任務的時候,計算任務必須等待;在做計算任務的時候,IO 任務必須等待。這顯然是一個急需解決的問題。
一直等到 IBM 開發(fā)的 OS/360 計算機才解決了這個問題,OS/360 可以說算是一個劃時代的標志,因為它有一個很重要的特點是能夠允許多道程序運行,并且能夠?qū)崿F(xiàn)多道任務之間的切換,這些任務可以是 IO 任務,也可以是計算任務。但是這些任務執(zhí)行于何處停止,何時進行切換卻沒有一個明確的標準。
后來出現(xiàn)了 MIT 開發(fā)的 MULTICS 操作系統(tǒng),這種操作系統(tǒng)是一種分時系統(tǒng),它允許每個任務都各自運行一段時間后再進行切換,這樣能夠兼顧所有的任務,使他們都能夠得到運行。雖然解決了分時復用的問題,但是不同任務所需要的時間并不一定是恒定的,所以 MULTICS 注定了只能是個過度。
后來出現(xiàn)了大名鼎鼎的 UNIX,由Dennis Ritchi 丹尼斯里奇和Ken Thompson 肯湯姆森共同開發(fā),UNIX 是一個簡化版的 MULTICS ,核心概念差不多,但是 UNIX 卻更加靈活和成功。奠定了小型化機器流行的基礎。
在 UNIX 開發(fā)出來不久,Andrew Tanenbaum 也開發(fā)出來了一套操作系統(tǒng) MINIX,不過這個操作系統(tǒng)是用于教學目的,沒有開源,而 Tanenbaum 就是寫現(xiàn)代操作系統(tǒng)的那個大佬。
又過了幾年,Linus Torvalds 基于 UNIX 操作系統(tǒng)開發(fā)了 Linux,一直流傳至今。
我沒有查到中斷到底是何時引入的,但是從 Linux 問世以來就已經(jīng)有了,而且 Linux 是基于 UNIX 開發(fā)的,可以認為 UNIX 就已經(jīng)引入中斷機制了,而且換個角度來說,UNIX 作為如此著名的操作系統(tǒng),應該會引入中斷機制的。
當然我知道大多數(shù)人對計算機歷史沒有太多興趣,所以我們現(xiàn)在還是切回主線了。
中斷的概念和相關原理
中斷是指計算機在運行過程中,由于某些原因(這個原因可以是系統(tǒng)外部、也可以是系統(tǒng)內(nèi)部或者程序出現(xiàn)緊急事件)不得不停下來當前正在執(zhí)行的任務,轉(zhuǎn)而處理其他任務的過程,在處理完其他事情后,計算機會返回繼續(xù)執(zhí)行當前任務,這個完整的過程就被稱為中斷(Interrupt)。
還有一種處理方式是輪詢,現(xiàn)代計算機一般都包含輸入輸出設備,在輪詢機制中,CPU 會不斷的順序詢問每個設備是否需要提供服務,如果需要提供服務,CPU 就會轉(zhuǎn)而為設備驅(qū)動進行服務;可以看到,這種輪詢的方式性能較差,而且比較耗費 CPU 資源。
輪詢的方式可以看做是一種被動要求 CPU 為其服務的方式,而中斷可以看做是一種主動要求 CPU 為其服務的方式。從我們?nèi)粘I詈蛯W習過程中就能夠知道,主動要求的方式效率要比被動詢問的方式要高,因為你肯定也經(jīng)歷過上課老師問同學們會不會的時候,有人主動站起來問問題要比老師問每個學生沒有回復效率要高的多。
在中斷的過程中,設備會向 CPU 發(fā)出的請求,而這個請求被稱為中斷請求(IRQ - Interrupt Request),CPU 針對中斷請求做出響應轉(zhuǎn)而執(zhí)行相關程序被稱為中斷服務程序(ISR - Interrupt Service Routine)或者叫中斷服務過程。
這里需要認識一個新的概念:中斷控制器(PIC - Programmable Interrupt Controller),中斷控制器負責管理設備發(fā)出的這些中斷請求,簡單來說它就是這些中斷請求的管理者。這個玩意會和設備的引腳相連接以便接收設備發(fā)出來的中斷信號,當設備激活 IRQ 時,中斷控制器會立刻檢測到并對其做出響應。不過真實的情況是,計算機無時無刻都在發(fā)出 IRQ,所以中斷控制器經(jīng)常會收到很多 IRQ,甚至有可能 CPU 正在執(zhí)行中斷過程的同時 PIC 還收到了 IRQ,這時中斷控制器需要對這些 IRQ 排出一個響應優(yōu)先級,來告知 CPU 應該首先執(zhí)行哪個中斷處理程序。
PIC 更多是適用于單核 CPU ,對于多核 CPU 來說并不適用,適用于多核 CPU 的是 APIC,APIC 我們后面簡單提到一些,不過目前還是以 PIC 為主,因為 Linux 0.11 用的是 PIC。
中斷的具體過程是這樣的:PIC 會向 CPU 的引腳發(fā)出一個中斷信號,CPU 知道產(chǎn)生了中斷信號后會立刻停下當前進程,并詢問 PIC 需要執(zhí)行哪個中斷請求,PIC 通過數(shù)據(jù)總線告知 CPU 中斷號,CPU 根據(jù)中斷號去 IDT(中斷向量表)中取得中斷向量并執(zhí)行中斷處理程序,處理完成后,CPU 會返回當前的任務繼續(xù)執(zhí)行。
上面聊到的這些中斷都是通過設備產(chǎn)生的中斷,這些中斷的本質(zhì)是外部設備產(chǎn)生的信號來告知操作系統(tǒng)其狀態(tài)的變化,這種中斷被稱為硬中斷;還有一種中斷是軟中斷,軟中斷通常是由軟件中引起中斷的指令產(chǎn)生的,比如 int 指令就會產(chǎn)生軟中斷,設備產(chǎn)生的硬中斷不會等待太長時間,響應速度比較快,而指令產(chǎn)生的軟中斷是一種推后的機制,響應速度不如硬中斷快。
80x86 的中斷系統(tǒng)
這部分主要介紹一下 x86 所使用的中斷控制芯片相關內(nèi)容,會涉及到一些嵌入式相關的知識。
80x86 組成的微機機系統(tǒng)中采用了 8259A 可編程中斷控制芯片。每個 8259A 芯片可以管理 8 個中斷源。通過多片級聯(lián)的方式,8259A 能構成最多管理 64 個中斷向量的系統(tǒng)。在 PC/AT 系列兼容機中,使用了兩片 8259A 芯片,可以管理 15 級中斷向量,如下圖所示:
從圖中可以看到,圖上方是主芯片,圖下方是從芯片,從芯片的 INT 引腳連接到主芯片的 IR2 引腳上,這也就是說,從芯片的中斷信號可以作為主芯片的輸入信號。
8259A 是一塊可編程芯片,可以通過 IN 和 OUT 指令對 8259A 進行編程,一旦完成了初始化編程,芯片就進入了操作狀態(tài),此時芯片可以隨時響應外部設備提出的中斷請求(IRQ0 - IRQ15)。通過中斷判優(yōu)選擇,芯片將當前最高優(yōu)先級的中斷請求作為中斷服務對象,并通過 INT 請求通知 CPU 外中斷請求到來,然后根據(jù)中斷號執(zhí)行中斷處理程序。
中斷向量表
上面提到過中斷向量表是 CPU 根據(jù)中斷號執(zhí)行中斷處理程序前需要查詢的"一張表",獲取中斷向量值后就可以對應中斷服務程序的入口值。
80x86 機器支持 256 個中斷,理論上每個中斷都需要安排一個中斷處理程序。在 80x86 實模式下,每個中斷向量由 4 個字節(jié)組成,這 4 個字節(jié)組成了一個中斷處理程序的段值和段內(nèi)偏移值,所以整個中斷向量表的大小是 1024 字節(jié)。在程序加電啟動時,程序進入實模式,此時 ROM BIOS 會在物理地址 0x0000:0x0000 處完成中斷向量表的初始化。在中斷向量表中,中斷向量號順序排列,每個中斷向量號占用 4 字節(jié),因此每個中斷向量的內(nèi)存位置就是 [0x0000:N 乘 4,0x0000:N+1 乘 4 - 1) 。
中斷向量表在 32 位保護模式下也叫做中斷描述符表,也是我們常說的 IDT 表。
IDT 表和中斷向量表都是描述中斷服務程序地址的表項,基本上中斷向量表和 IDT 表換湯不換藥,只不過 IDT 表除了有中斷服務程序的地址外,還包含有特權級和描述符類別等信息。
對于 Linux 內(nèi)核來說,中斷信號分為兩類:硬件中斷和軟件中斷,每個中斷是由 0 - 255 之間的一個數(shù)字來標識。對于中斷 int0 - int31 來說,每個中斷的功能都由 intel 制定或保留用,這些屬于軟件中斷,但是 intel 公司稱之為異常。叫做異常也是可以理解的,因為這些中斷都是在探測到異常情況下發(fā)出的。中斷 int32 - int255 可以由用戶自己設定。常見的硬件和軟件中斷描述見下表。
在 Linux 系統(tǒng)中,將 int32 - int47 對應于 8259A 中斷控制芯片發(fā)出的硬件中斷請求信號 IRQ0 - IRQ15,并把程序編程發(fā)出的系統(tǒng)調(diào)用中斷設置為 int128 ,也就是 0x80。
下面是 8259A 芯片中斷請求發(fā)出的中斷號列表:
中斷請求號 | 中斷號 | 用途 |
---|---|---|
IRQ0 | 0x20(32) | 8253 發(fā)出的 100HZ 時鐘中斷 |
IRQ1 | 0x21(33) | 鍵盤中斷 |
IRQ2 | 0x22(34) | 接連從芯片 |
IRQ3 | 0x23(35) | 串行口 2 |
IRQ4 | 0x24(36) | 串行口 1 |
IRQ5 | 0x25(37) | 并行口 2 |
IRQ6 | 0x26(38) | 軟盤驅(qū)動器 |
IRQ7 | 0x27(39) | 并行口 1 |
IRQ8 | 0x28(40) | 實時鐘中斷 |
IRQ9 | 0x29(41) | 保留 |
IRQ10 | 0x2a(42) | 保留 |
IRQ11 | 0x2b(43) | 保留(網(wǎng)絡接口) |
IRQ12 | 0x2c(44) | PS/2 鼠標口中斷 |
IRQ13 | 0x2d(45) | 數(shù)學協(xié)處理器中斷 |
IRQ14 | 0x2e(46) | 硬盤中斷 |
IRQ15 | 0x2f(47) | 保留 |
在系統(tǒng)剛剛初始化后,內(nèi)核在 head.s 程序中會對所有 256 個中斷向量進行默認設置。默認設置就是給這些中斷向量隨便設置一個初值,設置這個值的目的是為了防止出現(xiàn)一般保護性錯誤。
一般保護性錯誤:是指在英特爾 x86 架構和 AMDx86-64 架構和其它架構中的一種中斷情況,指正在運行的程序(內(nèi)核或用戶態(tài)程序)違反處理器架構中保護措施的情況。
最常見的情況就是
Linux 中的這些中斷不會所有的都用到,有些中斷是保留中,另外對于系統(tǒng)中所使用的一些中斷,內(nèi)核會在其初始化過程中重新設置這些中斷描述符,讓他們指向?qū)嶋H的處理過程。
另外,在設置中斷描述符表 IDT 表時 Linux 內(nèi)核使用了中斷門和陷阱門兩種門描述符。它們之間的區(qū)別在于對標志寄存器 EFLAGS 中的中斷允許標志 IF 的影響。由中斷門描述符執(zhí)行的中斷會復位 IF 標志,因此可以避免其他中斷干擾當前中斷的處理。隨后中斷結束后指令 iret 會恢復 IF 標志的原值;而通過陷阱門執(zhí)行的中斷不會響應 IF 標志。
這里需要說一下兩個指令 cli 和 sti,為了避免競爭條件對臨界代碼的干擾,在 Linux 0.11 內(nèi)核中很多地方都使用了 cli 和 sti 指令。cli 指令用于復位 CPU 標志寄存器 EFLAGS 中的中斷標志,使得系統(tǒng)在執(zhí)行 cli 指令后不會響應外部中斷。sti 指令用于設置標志寄存器中的中斷標志,能夠讓 CPU 識別并響應外部設備發(fā)出的中斷。這倆相當于是個可逆的關系。
當一段代碼進入可能引起競爭條件的臨界代碼區(qū)時,內(nèi)核中就會使用 cli 指令來關閉對外部中斷的響應,而在執(zhí)行完競爭代碼區(qū)時內(nèi)核就會執(zhí)行 sti 指令以重新允許 CPU 響應外部中斷。如果不設置 cli 和 sti 的話,就可能引起對臨界代碼的多重寫操作,導致數(shù)據(jù)不一致,產(chǎn)生崩潰現(xiàn)象。
審核編輯:劉清
-
嵌入式系統(tǒng)
+關注
關注
41文章
3662瀏覽量
130591 -
Linux系統(tǒng)
+關注
關注
4文章
601瀏覽量
28146 -
PIC
+關注
關注
8文章
507瀏覽量
88479 -
中斷處理
+關注
關注
0文章
94瀏覽量
11165 -
中斷控制器
+關注
關注
0文章
59瀏覽量
9596
發(fā)布評論請先 登錄
相關推薦
VxWorks下FMPC860的中斷處理機制及其應用
VxWorks下MPC860的中斷處理機制及其應用
VxWorks下MPC860的中斷處理機制及其應用
VxWorks下MPC860的中斷處理機制及其應用
VxWorks下基于ML507嵌入式系統(tǒng)的中斷處理

單片機的中斷系統(tǒng)的概念控制系統(tǒng)和處理過程及編程及應用資料概述

linux驅(qū)動之中斷處理過程C程序部分
了解Linux中斷處理原理

STM32Cube HAL庫中斷處理機制 以及回調(diào)函數(shù)實現(xiàn)原理
Linux中斷處理機制

評論