這是我們瘋狂內核系列的中斷處理專題開山之作,中斷,廣義的來說通常被定義爲一個事件,該事件觸發改變處理器執行指令的順序。狹義地來說,針對80x86體系,中斷被分爲中斷和異常,又叫同步中斷和異步中斷。注意廣義的中斷和狹義的中斷千萬不要混淆,以後我的博文中所有所謂的“中斷”二字,就是指狹義的中斷,即Linux處理80x86異步中斷的細節。我們首先必須好好理清一下80x86體系中,中斷和異常的區別:
中斷:由其他硬件依照CPU時鐘信號隨機產生。
異常:由CPU本身執行指令時,CPU控制單元在一條指令終止之後產生。
更進一步,Intel文檔中又把中斷和異常繼續進行了細分:
中斷:
1. 可屏蔽中斷:當中斷被屏蔽,則CPU控制單元就忽略它。這裏提一下,所有的IRQ中斷都是可屏蔽中斷。
2. 非可屏蔽中斷:總由CPU辨認並處理。所以,其爲非常緊急的硬件故障。
異常:
1. 處理器探測到得異常
(1)故障(fault)
通常可以糾正,所謂的“糾正”,就是在執行一條指令時發現故障,轉而執行對應的異常處理程序;一旦糾正完畢,即異常處理程序完成,程序就可以在不失連貫性的情況下,重新執行剛纔那條發現故障的指令。保存在eip寄存器中的值是引起故障的指令地址,因此,當異常處理程序終止時,那條指令會被重新執行。
(2)陷阱(trap)
陷阱的主要用途是爲了調試程序。在這種情況下,eip中存放的不是引起陷阱的指令,而是下一個即將執行的指令。陷阱的中斷信號的作用是通知調試程序一條特殊指令已被執行。一旦用戶檢查到調試程序所提供的數據,他就可能要求被調試程序從下一條指令重新開始執行。
(3)異常終止(abort)
發生一個嚴重錯誤;CPU控制單元出了問題,不能在eip寄存器中保存引起異常指令所在的確切位置。所以,除了強制終止受影響的進程外,別無選擇。
2. 軟中斷
軟中斷由程序員通過int或int3指令觸發的。當into(檢查溢出)和bound(檢查地址出界)指令檢查的條件不爲真時,也會引起軟中斷。CPU把軟中斷作爲陷阱來處理,也叫編程異常。這樣的異常有兩種常用的用途:執行系統調用以及給調試程序通報一個特定的事件。
每個中斷和異常是由0~255之間的一個數來標識的,我們把這個八位無符號整數叫做向量。非屏蔽中斷的向量和異常的向量是固定的,而可屏蔽中斷的向量可以通過對中斷控制器的編程來改變。
向量範圍 |
用途 |
0-19 (0x0-0x13) |
非屏蔽中斷和異常 |
20-31 (0x14-0x1f) |
Intel保留 |
32-127 (0x20-0x7f) |
外部中斷 (IRQs) |
128 (0x80) |
用於系統調用的可編程異常(重點) |
129-238 (0x81-0xee) |
外部中斷 (IRQs) |
239 (0xef) |
本地APIC時鐘中斷(重點) |
240 (0xf0) |
本地APIC高溫中斷(在Pentium 4模型中引入) |
241-250 (0xf1-0xfa) |
由Linux留作將來使用 |
251-253 (0xfb-0xfd) |
處理器間中斷 |
254 (0xfe) |
本地APIC錯誤中斷(當本地APIC檢測到一個錯誤條件時產生) |
255 (0xff) |
本地APIC僞中斷(CPU屏蔽某個中斷時產生) |