一.什麼異常?
異常我們可以籠統的理解爲中斷,它的範圍更寬泛一點,復位啊,外部中斷啊,都屬於異常。都是向cpu請求打斷正常的程序流程,進入特定程序的一種機制。
二. ARM中的7種異常種類
優先級 |
異常 |
異常模式 |
描述 |
用途 |
1(最高) |
復位異常(reset) |
SVC(特權模式) |
復位電平有效時,產生復位異常,程序跳轉到復位處理程序處執行 |
進行操作系統高級處理 |
2 |
數據中止異常(data abort) |
Abort(數據訪問中止模式) |
處理器數據訪問指令的地址不存在,或該地址不允許當前指令訪問時產生數據中止異常 |
虛存和存儲器保護 |
3 |
快速中斷異常(FIQ) |
FIQ(快速中斷模式) |
快速中斷請求引腳有效,且CPSR中的F位爲0時,產生FIQ異常 |
快速中斷請求處理 |
4 |
外部中斷異常(IRQ) |
IRQ(外部中斷模式) |
外部中斷請求有效,且CPSR中的I位爲0時,產生IRQ異常 |
外部中斷請求處理 |
5 |
預取指令中止異常(prefetch abort) |
Abort(數據訪問中止模式) |
處理器預取指令的地址不存在,或該地址不允許當前指令訪問,產生指令預取中止異常 |
虛存和存儲器保護 |
6 |
軟中斷異常 (swi) |
SVC(特權模式) |
執行SWI指令產生,用於用戶模式下的程序調用特權操作指令 |
操作系統高級處理 |
7(最低) |
未定義指令異常 (undefined interrupt) |
Undefined(未定義指令終止模式) |
遇到不能處理的指令時,產生未定義指令異常 |
軟件模擬硬件協處理器 |
注:每一種異常都會導致內核進入一種特定的模式,用戶模式和系統模式下,不可以通過異常進入,只能通過編程改變CPSR來進入。(用戶模式下不能讀寫cpsr,只能通過異常回到其他模式)
三. 異常和向量表地址,返回地址
存儲器映射地址0x00000000是爲向量表(32位字節)保留的(有的處理器向量表選擇在存儲空間的高地址0xffff0000開始)
有的支持通過設置CP15的C12寄存器將向量表首地址設置到任意地址。
向量表地址 |
異常 |
返回地址 |
說明 |
0x00000000 |
復位異常(reset) |
-- |
復位沒有定義LR |
0x00000004 |
未定義指令異常 (undefined interrupt) |
LR |
LR指向未定義指令的下一條指令 |
0x00000008 |
軟中斷異常 (swi) |
LR |
LR指向SWI指令的下一條指令 |
0x0000000C |
預取指令中止異常(prefetch abort) |
LR-4 |
LR指向導致預取指令異常的那條指令 |
0x00000010 |
數據中止異常(data abort) |
LR-8 |
LR指向導致數據中止異常的指令 |
0x00000018 |
外部中斷異常(IRQ) |
LR-4 |
LR指向發生異常時正在執行的指令 |
0x0000001C |
快速中斷異常(FIQ) |
LR-4 |
LR指向發生異常時正在執行的指令 |
注:
- 異常是隨機產生的,當異常發生時,處理器會把PC設置爲一個特定的存儲器地址,這一地址放在被稱爲向量表的特定地址範圍內。(向量表的入口是一些跳轉指令,跳轉到專門處理某個異常或中斷的子程序)
- 每一個異常發生時總是從異常向量表開始跳轉,最簡單快速的方法是向量表中的每一條指令直接跳到對應的異常處理函數,快速中斷處理函數就可以直接從地址0x1C開始,省下一條跳轉指令。
四.SWI 軟中斷
軟中斷是利用硬件中斷的概念,用軟件方式進行模擬,實現從用戶模式切換到特權模式並執行特權程序的機制。
硬件中斷是由電平的物理特性決定,在電平變化時引發中斷操作,而軟中斷是通過一條具體指令SWI,引發中斷操作,也就是說用戶程序裏可以通過寫入SWI指令來切換到特權模式,當CPU執行到SWI指令時會從用戶模式切換到管理模式下,執行軟件中斷處理。由於SWI指令由操作系統提供的API封裝起來,並且軟件中斷處理程序也是操作系統編寫者提前寫好的,因此用戶程序調用API時就是將操作權限交給了操作系統,所以用戶程序還是不能隨意訪問硬件。
先來了解下SWI指令。
SWI指令編碼中immed_24爲24位任意有效立即數(範圍0~2^24-1),當該指令被執行時系統產生軟中斷異常,切換到管理模式下。用戶程序切換到管理模式下後,進入到軟中斷處理程序,通常軟中斷異常處理程序都是系統開發人員提前寫好的,SWI切換到了特權模式,執行的是系統開發人員寫好的異常處理程序
SWI指令後面的24立即數是幹什麼用的呢?用戶程序通過SWI指令切換到特權模式,進入軟中斷處理程序,但是軟中斷處理程序不知道用戶程序到底想要做什麼?SWI指令後面的24位用來做用戶程序和軟中斷處理程序之間的接頭暗號。通過該軟中斷立即數來區分用戶不同操作,執行不同內核函數。如果用戶程序調用系統調用時傳遞參數,根據ATPCSC語言與彙編混合編程規則將參數放入R0~R4即可。
五.SWI 在系統調用中的應用
1.Unix系統通過向內核發出系統調用(system call)實現了用戶態進程和硬件設備之間的大部分接口。系統調用是操作系統提供的服務,用戶程序通過各種系統調用,來引用內核提供的各種服務,系統調用的執行讓用戶程序陷入內核,該陷入動作由swi軟中斷完成。
2. ARM Linux 系統利用SWI指令來從用戶空間進入內核空間。SWI指令用於產生軟件中斷,從而實現從用戶模式變換到管理模式,CPSR保存到管理模式的SPSR,執行轉移到SWI向量。在其他模式下也可使用SWI指令,處理器同樣地切換到管理模式。
六.SWI 異常處理過程
直接看下面的實例代碼: