中斷和異常
中斷訊號的處理方式:
分緊急部分和不緊急部分
中斷處理**必須能夠重入,以便能夠中斷巢狀
中斷和異常的產生
乙個irq(interrupt request)代表中斷控制器上的一根中斷線,和乙個中斷向量
單cpu:可程式設計中斷控制器(pic)
多cpu:改進的可程式設計中斷控制器(apic):
乙個額外的apic負責連線外部中斷線(i/o apic),並與每個local apic通訊。i/o apic內部:
可程式設計暫存器
訊息單元 (跟locel apic通訊)
選擇目標cpu的方式:
每apic乙個id,cpu可通過它互相發中斷(在icr(中斷命令暫存器)中,指定目標apic的id和中斷向量就可以)。
apic在單cpu系統也可用
指令和記憶體
段、頁
其他
斷點:int3指令觸發。斷點指令
溢位:當of位設定了時,into指令觸發
流產(abort):嚴重錯誤(硬體失敗,或是系統資料出現錯誤); 或是cpu控制單元出錯,無法儲存eip。
程式設定的異常:
2號異常用於不可遮蔽中斷
[tr]中斷號分配[/tr]
0 - 19
不可遮蔽的中斷和異常
20 - 31
intel 保留
32 - 127
irq128
系統呼叫用到的軟體異常
129-238
irq239
本地apic的timer
240本地apic的熱中斷 (thermal interrupt)
241 - 250
linux擴充套件
251 - 253
cpu之間互發中斷訊息
254 錯誤中斷,本地apic探測到乙個錯誤狀況
255 本地apic 偽造中斷。告知裝置發出了乙個被遮蔽的中斷
中斷異常的硬體處理
[tr]指令中斷號[/tr]
int3
3(斷點)
[tr]指令中斷號[/tr]
into
4(溢位)
bound
5(位址邊界檢查))
int $0x80
128(系統呼叫)
handler_name: /*儲存暫存器的彙編***/ call do_handle_name /*真正的處理, c函式*/
set_task_gate (n, gdt)
若有中斷
儲存eflags, cs, eip到棧中,以備恢復。
如果異常帶來乙個硬體錯誤碼,存在棧裡。
load 中斷處理的的cs(段選擇符), eip (段選擇符和offset),開始處理
中斷返回: 用iret指令返回. 控制單元做的事:
中斷、異常的軟體處理
巢狀的好處:
硬中斷 - 每cpu乙個 ,所有cpu的在乙個陣列理:irq_ctx hardirq_stack [nr_cpu]。 hardirq_ctx[nr_cpu]存著每個棧的基址,用於快速定位
軟中斷 - 每cpu乙個, 所有cpu的在乙個陣列理:irq_ctx softirq_stack [nr_cpu]。 softirq_ctx[nr_cpu]存著每個棧的基址,用於快速定位。
異常的軟體處理:
呼叫hander:
handler的處理方式:
以jmp到彙編函式ret_from_exception的方式 返回
二次失敗異常,用task_gate處理
處理沒實現時,用ignore_init替代:
如果核心態出異常:
中斷的軟體處理
可延時部分: 用於向程序(不一定是當前程序)的使用者空間拷貝資料。可被延時較長時間。
irq少,裝置多
irq動態分配
給乙個裝置分配irq
handler_data :pic物件裡的函式用到的資料
action:這個irq上的所有isr, 以鍊錶形式。每乙個節點對應乙個裝置,節點的結構irq_action:
mask - 沒用
next - 下乙個節點指標
depth:irq被禁用的層次
統計資訊,用來防止意外中斷:
裝載使用者資料段
準備引數: 棧指標 -> eax
呼叫do_irq (引數在eax中): 起封裝「棧切換」的作用
呼叫__do_irq() (解決多cpu問題,每次改變status都有加鎖)
如果棧切換了,切回原來的棧
執行irq_exit巨集:減少巢狀層次,執行可延遲函式
用ret_from_intr()結束中斷處理
遺漏的中斷
[tr]向量號(_vector左邊的是中斷名字)目標cpu作用接收者的動作附加說明[/tr]
call_function_vector(0xfb)
除發出者外的所有cpu
使接收者執行某乙個函式
發回ack, 執行函式
函式指標call_data裡
rescheduele_vector(0xfc)
某乙個,某幾個cpu
使其排程
發回ack, 排程
invalid_tlb_vector(0xfd)
所有cpu
強制其tlb無效
目標cpu
所有除了自己
自己指定
函式xyz
allallbutself
self
maks
釋放乙個節點(fixme: 鍊錶上所有節點?):free_irq
irq訊號在多cpu間分配
如果硬體不支援仲裁優先順序變換:
型別位irq_stat的irq_cpustat_t陣列,每個cpu乙個元素。儲存每個cpu最近處理irq的情況。用於平衡每個cpu的irq處理。
鍊錶陣列初始化 init_irq():
softirq和tasklet
可重入。
tasklet反之。使驅動編寫簡單。
基本操作:
softirq
設定,即把乙個函式設定在softirq_vec的乙個元素:open_softirq(indx, action, data)
啟用,raise_softirq(index).
多核心棧時,用irq_ctx內的preempt_count, 但它一般是個正數。fixme: 那何時啟用?
如果都為零,說明不巢狀在中斷上下文中。呼叫wakeup_softirqd()來喚醒執行軟中斷的核心執行緒ksoftirqd
raise_softirq的開始、結束時要禁止中斷,恢復中斷
執行 softirqd不斷檢查、執行
count:禁用次數。fixme: 為什麼其他softirq沒有單獨的count
func
data
next
介面:
執行:就是softirq_vec裡前兩個元素的函式是tasklet_hi_action, tasklet_action
work queue(工作列隊)
thread:執行該鍊錶函式的工作執行緒
run_depth:
more_work:等待列隊,等待新的函式的工作執行緒阻塞在這裡
work_done:等待列隊, 等待工作列隊flush完畢的程序阻塞在這裡
remove_sequence:用於判斷哪些哪些函式是flush以後才來的。
insert_sequence:用於判斷哪些哪些函式是flush以後才來的。
介面
插入乙個函式:
執行:
等待執行完:
核心預定義的工作列隊events: 包含不同kernel層的函式和i/o驅動。 在keventd_wq陣列裡存著不同的工作列隊
從中斷和異常中返回
如果有巢狀的kcp(kernel control path),且不是虛擬8086模式,則恢復kernel。否則恢復使用者空間
恢復到使用者空間:
恢復:
中斷和異常
中斷通常定義為乙個事件,該事件改變處理器執行的指令順序。中斷通常分為同步中斷與非同步中斷。異常是同步的,i o中斷是非同步的。中斷可以分為 i o裝置發出的中斷請求 irq 都可以被遮蔽,乙個中斷被遮蔽以後,控制單元就忽略他。只有硬體故障等幾個危急事件才是非遮蔽中斷。異常可以分為 可以糾正的異常,例...
中斷和異常
1 中斷機制的誕生 早期計算機,各程式只能序列執行,系統資源利用率低,為了解決這個問題,從而誕生了作業系統 作為計算機的管理者 引入中斷機制,實現了多道程式併發執行。本質 發生中斷就意味著需要作業系統介入,開展管理工作。2 中斷的概念和作用 1 當中斷發生時,cpu立即進入核心態。2 當中斷發生後,...
中斷和異常
這周主要學習了中斷和異常,在這裡把整章知識梳理一下,做乙個總結。工作佇列沒有完成 一 什麼是中段 中斷 外部中段 是對外部裝置而言,i o需要服務時處理器去相應。異常 內部中斷 是為了解決機器執行時所出現的某些隨機事件及程式設計方便而出現的。中斷可分為遮蔽中斷和不可遮蔽中斷 異常分為故障 陷阱和終止...