深度揭秘中斷機(jī)制:硬中斷與軟中斷的實(shí)現(xiàn)原理與代碼實(shí)戰(zhàn)
中斷的實(shí)現(xiàn)原理可以分為硬中斷和軟中斷兩類,以下是具體描述:
一、硬中斷的實(shí)現(xiàn)原理
硬中斷是由硬件設(shè)備觸發(fā)的中斷信號(hào),它的處理機(jī)制如下:
1.1 觸發(fā)機(jī)制
- 硬件設(shè)備發(fā)生事件(例如鍵盤按鍵、網(wǎng)卡收到數(shù)據(jù)包等)。
- 設(shè)備通過中斷控制器(如 PIC、APIC)向 CPU 發(fā)出中斷信號(hào)。
- CPU 檢測(cè)到中斷信號(hào)后,停止當(dāng)前正在執(zhí)行的指令,將上下文保存到堆棧。
1.2 中斷向量
- 每種中斷類型都有對(duì)應(yīng)的中斷向量號(hào),中斷控制器會(huì)將中斷號(hào)發(fā)送給 CPU。
- CPU 根據(jù)中斷向量號(hào)找到對(duì)應(yīng)的中斷處理程序的入口地址(通常通過中斷向量表,IVT,或 IDT)。
1.3 中斷處理
- CPU 禁用中斷(或者切換到更高優(yōu)先級(jí)中斷級(jí)別)以保護(hù)中斷處理過程。
- 跳轉(zhuǎn)到對(duì)應(yīng)的中斷處理程序(ISR,Interrupt Service Routine)。
- 中斷處理完成后,通過 iret 指令恢復(fù)之前的上下文,重新開啟中斷并返回。
二、軟中斷的實(shí)現(xiàn)原理
軟中斷是由軟件觸發(fā)的“模擬中斷”,其機(jī)制通常依賴操作系統(tǒng)的中斷管理機(jī)制,主要特點(diǎn)如下:
2.1 軟中斷觸發(fā)
- 主動(dòng)觸發(fā): 軟中斷由軟件通過特殊指令或操作觸發(fā)。例如:
在 x86 架構(gòu)中使用 int 指令觸發(fā)軟中斷(如 int 0x80 是 Linux 的系統(tǒng)調(diào)用接口)。
ARM 中通過 svc 指令(Supervisor Call)實(shí)現(xiàn)系統(tǒng)調(diào)用。
- 由操作系統(tǒng)調(diào)度: 操作系統(tǒng)可通過標(biāo)記某些任務(wù)為軟中斷任務(wù),稍后由內(nèi)核線程處理。
2.2 軟中斷處理
軟中斷依賴于內(nèi)核的中斷上下文機(jī)制,通常包括以下步驟:
- 軟中斷向量: 軟中斷也有向量號(hào),對(duì)應(yīng)不同的處理函數(shù)。
- 優(yōu)先級(jí)處理:
硬中斷處理優(yōu)先于軟中斷。
軟中斷處理通常延遲到硬中斷處理完成后執(zhí)行。
- 實(shí)現(xiàn)細(xì)節(jié):
- 在 Linux 中,軟中斷實(shí)現(xiàn)為一種輕量級(jí)的機(jī)制(例如 softirq 或 tasklet)。
- softirq 是靜態(tài)定義的,而 tasklet 是 softirq 的更高層抽象,用于特定任務(wù)(例如網(wǎng)絡(luò)數(shù)據(jù)包處理)。
2.3 系統(tǒng)調(diào)用的例子
在 Linux 系統(tǒng)中,系統(tǒng)調(diào)用通過軟中斷實(shí)現(xiàn):
- 應(yīng)用程序通過軟中斷指令(如 int 0x80 或 syscall 指令)將用戶態(tài)切換到內(nèi)核態(tài)。
- 內(nèi)核根據(jù)調(diào)用號(hào)找到對(duì)應(yīng)的系統(tǒng)調(diào)用處理函數(shù)。
- 處理完成后返回用戶態(tài)。
硬中斷代碼實(shí)現(xiàn)
硬中斷的處理代碼主要存在于內(nèi)核中,與硬件直接交互。以下以 Linux 的硬中斷注冊(cè)和處理為例。
硬中斷注冊(cè)與處理
硬件中斷在 Linux 中通過 request_irq 注冊(cè),以下是典型代碼:
#include <linux/interrupt.h>
static irqreturn_t my_irq_handler(int irq, void *dev_id) {
// 中斷處理邏輯
printk(KERN_INFO "Interrupt handled for IRQ %d\n", irq);
return IRQ_HANDLED; // 表示中斷已處理
}
static int __init my_module_init(void) {
int irq_number = 1; // 示例:鍵盤中斷號(hào)
int ret;
// 注冊(cè)中斷處理程序
ret = request_irq(irq_number, my_irq_handler, IRQF_SHARED, "my_irq_handler", (void *)my_irq_handler);
if (ret) {
printk(KERN_ERR "Failed to request IRQ %d\n", irq_number);
return ret;
}
printk(KERN_INFO "IRQ %d registered successfully\n", irq_number);
return 0;
}
static void __exit my_module_exit(void) {
int irq_number = 1; // 示例:鍵盤中斷號(hào)
// 釋放中斷
free_irq(irq_number, (void *)my_irq_handler);
printk(KERN_INFO "IRQ %d released\n", irq_number);
}
module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");
代碼說明:
- request_irq 注冊(cè)中斷處理程序:
第一個(gè)參數(shù):中斷號(hào)。
- 第二個(gè)參數(shù):中斷處理函數(shù)(my_irq_handler)。
- 第三個(gè)參數(shù):標(biāo)志位(如 IRQF_SHARED 表示共享中斷)。
- 第四個(gè)參數(shù):中斷的名字。
- 第五個(gè)參數(shù):共享中斷時(shí)的標(biāo)識(shí)。
- 中斷處理函數(shù):
- 在中斷處理函數(shù) my_irq_handler 中,處理硬件中斷信號(hào)。
- IRQ_HANDLED 表示中斷已被正確處理。
- 釋放中斷:
- 在模塊卸載時(shí),使用 free_irq 釋放資源。
軟中斷代碼實(shí)現(xiàn)
軟中斷的實(shí)現(xiàn)可以通過 softirq 或更高層次的 tasklet 完成。以下以 softirq 為例。
軟中斷定義與觸發(fā)
在 Linux 內(nèi)核中,softirq 通常通過 open_softirq 定義,通過 raise_softirq 或硬件中斷間接觸發(fā)。
軟中斷注冊(cè)與實(shí)現(xiàn)
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
// 定義軟中斷處理函數(shù)
static void my_softirq_handler(struct softirq_action *action) {
printk(KERN_INFO "SoftIRQ executed\n");
}
// 初始化模塊,注冊(cè)軟中斷
static int __init my_module_init(void) {
open_softirq(1, my_softirq_handler); // 定義軟中斷類型 1 的處理函數(shù)
printk(KERN_INFO "SoftIRQ registered\n");
// 手動(dòng)觸發(fā)軟中斷
raise_softirq(1);
return 0;
}
// 卸載模塊
static void __exit my_module_exit(void) {
printk(KERN_INFO "SoftIRQ module exited\n");
}
module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");
代碼說明:
- open_softirq 注冊(cè)軟中斷:
- 第一個(gè)參數(shù):軟中斷的類型編號(hào)。
- 第二個(gè)參數(shù):軟中斷處理函數(shù)。
- 觸發(fā)軟中斷:
- 使用 raise_softirq 觸發(fā)指定類型的軟中斷。
- 內(nèi)核會(huì)在適當(dāng)時(shí)機(jī)(例如硬中斷退出后或 ksoftirqd 線程調(diào)度時(shí))處理軟中斷。
- 處理軟中斷:
- 內(nèi)核調(diào)度系統(tǒng)會(huì)調(diào)用軟中斷處理函數(shù)(如 my_softirq_handler)。
硬中斷和軟中斷的區(qū)別
屬性 | 硬中斷 | 軟中斷 |
觸發(fā)方式 | 由硬件設(shè)備觸發(fā) | 由軟件指令觸發(fā) |
優(yōu)先級(jí) | 更高,優(yōu)先處理 | 較低,通常延遲執(zhí)行 |
實(shí)現(xiàn)方式 | 硬件 + 操作系統(tǒng)內(nèi)核支持 | 依賴操作系統(tǒng)內(nèi)核調(diào)度 |
應(yīng)用場(chǎng)景 | 處理硬件事件(如 IO、中斷請(qǐng)求) | 系統(tǒng)調(diào)用、內(nèi)核任務(wù)延遲處理 |
本文轉(zhuǎn)載自微信公眾號(hào)「 快樂程序猿」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系快樂程序猿公眾號(hào)。