基于 ARM Linux 中斷、異常的處理分析
本文是基于ARM S3C2410X 系統的Linux 2.6 中斷、異常和系統調用的處理分析。
主要有以下幾個部分:
1. ARM 的硬件中斷機制
2. Linux 2.6 對 ARM 中斷向量表的初始化
3. Linux 2.6 對 ARM 中斷、異常的處理(從匯編-->C 語言函數;asm_do_IRQ )
一、 ARM 的硬件中斷機制
1、中斷的基本概念
在嵌入式系統中外部設備的功能實現主要是依靠中斷機制來實現的,即將設
備功能程序的實現以中斷服務子程序的形式進行組織。
中斷 (interrupt )通常被定義為一個事件,該事件改變處理器執行的指令順序。
這樣的事件與 CPU 芯片外部硬件電路產生的電信號相對應。
中斷的產生 每個能夠發出中斷請求的硬件設備控制器都有一條稱為
IRQ(Interrupt ReQuest) 的輸出線。所有的IRQ 線都與一個中斷控制器的輸入引腳
相連,中斷控制器與 CPU 的INTR 引腳相連。
設備
設備
控制器
中斷
控制器
IRQ
CPU
INTR
中斷向量 每個中斷和異常由 0~255 之間的一個數(8 位)來標識,Intel 稱其為
中斷向量。
中斷描述符表 (Interrupt Descriptor Table ,IDT )是一個系統表,它與每一個中斷
或異常向量相聯系,每一個向量在表中有相應的中斷或異常處理程序的入口地
址。內核在允許中斷發生前,必須適當地初始化 IDT 。表中的每一項對應一個中
斷或異常向量,每個向量由 8 個字節組成。因此,最多需要 256*8=2048 字節來
存放 IDT 。CPU 的idtr 寄存器指向 IDT 表的物理基地址。
2、中斷和異常的硬件處理
在內核被 Init 進程初始化后,CPU 運行在保護模式下。當執行了一條指令后,
cs 和 eip 這對寄存器包含了下一條將要執行的指令的邏輯地址。在執行這條指令
之前,CPU 控制單元會檢查在運行前一條指令時是否發生了一個中斷或者異常。
如果發生了一個中斷或異常,那么 CPU 控制單元執行下列操作:
(1) 確定與中斷或者異常關聯的向量 i (0~255 )。
(2) 讀由 idtr 寄存器指向的 IDT 表中的第 i 項。
(3) 從 gdtr 寄存器獲得 GDT 的基地址,并在 GDT 中查找,以讀取IDT 表項中的
選擇符所標識的段描述符,這個描述符指定中斷或異常處理程序所在段的基
地址。
(4) 確定中斷是由授權的發生源發出的。
中斷:中斷處理程序的特權不能低于引起中斷的程序的特權(當前特權級CPL
—對應 CS 寄存器中的低兩位 其值應該小于段描述符—對應 GDT 表
項中的描述符特權級 DPL ,特權級高于DPL ,即當前代碼是能夠訪問
相應的段的,產生一個“General protection ”異常);
編程異常:還需進一步比較 CPL 與對應 IDT 表項中的門描述符的 DPL 。
即當 CPL 的特權級高于 GDT 表項中的描述符特權級 DPL ,但低于 IDT 表
項中的門描述符的 DPL ,就是異常。
(5) 檢查是否發生了特權級的變化,一般指是否由用戶態陷入了內核態。也就是
說 CPL 是否不同于所選擇的段描述符的 DPL ,如果是,控制單元必須開始使
用與新的特權級相關的堆棧,通過以下操作來做到這點:
A 、讀tr 寄存器,訪問運行進程的 TSS 段;
B 、用與新特權級相關的棧段和棧指針裝載 ss 和 esp 寄存器。這些值可以在
進程的 TSS 段中找到;
C、在新的棧中保存 ss 和 esp 以前的值,這些值指明了與舊特權級相關的棧
的邏輯地址。
(6) 若發