【自制操做系統08】中斷

因爲中斷這塊的知識和代碼都佔較大篇幅,所以分紅兩章來說,本章不包含任何中斷的代碼,只講理論部分,以及中斷的大概流程。代碼實現部分由下一章來說解html

【自制操做系統09】中斷的代碼實現linux

1、到目前爲止的程序流程圖

爲了讓你們清楚目前的程序進度,畫了到目前爲止的程序流程圖,以下。git

2、什麼是中斷

這裏咱們先從形象的角度來描述,中斷就是讓操做系統中止手中正在進行的工做,先把中斷信號對應的處理程序執行完畢,再回到以前的程序中繼續進行,這樣一個機制。編程

一個很形象的說法是,咱們的操做系統就是 中斷驅動 的,能夠把操做系統簡單理解爲一個 死循環,無時無刻不在等待中斷的來臨,被動 地執行相應的任務。數組

while(true){
    操做系統代碼
}

3、中斷的分類

外部中斷

外部中斷經過兩個引腳鏈接到 CPU 上,一個是可屏蔽中斷 INTR,一個是不可屏蔽中斷 NMIide

  • INTR:硬盤、打印機、網卡等設備發出的中斷信號,可經過 eflags 寄存器的 IF 位將全部這些外部設備的中斷屏蔽
  • NMI:電源掉電、內存讀寫錯誤、總線奇偶校驗錯誤等災難性的錯誤,不可屏蔽,CPU 必須馬上處理

對於可屏蔽中斷,Linux 的處理方式是分紅 上半部下半部。上半部執行時關閉中斷,馬上執行完畢;下半部執行時打開中斷,此時若是有其餘中斷進來,則讓給其餘中斷(也是上半部執行完畢)。學習

內部中斷

內部中斷可分爲 軟中斷 和 異常,兩者均是不可屏蔽的(即不受 eflags 的 IF 位影響)測試

  • 軟中斷:就是軟件發起的中斷,最多見的也是咱們以後進行系統調用的,就是 int 8位當即數,可表示 256 中中斷。還有一些不經常使用的,甚至能夠叫作異常,下面簡單列出
    • int3:中斷向量號3,調試斷點指令
    • into:中斷向量號4,中斷溢出指令
    • bound:中斷向量號5,檢查數組索引越界指令
    • ud2:中斷向量號6,未定義指令,經常使用於軟件測試中主動發起這個中斷
  • 異常:指令執行期間 CPU 內部產生的錯誤引發,如分母爲 0 將發起 6 號中斷(異常),未定義的指令發起 6 號中斷
    • Fault(故障):可恢復的錯誤。發生此中斷時,CPU 將機器狀態恢復到異常以前的狀態,以後調用中斷處理程序,結束後返回。常見的如 缺頁異常
    • Trap(陷阱):有意的異常。一般是調試程序中用 int3 指令主動觸發。
    • Abort(終止):不可恢復的異常。直接將此程序從進程表中去掉。

4、中斷號

咱們知道一箇中斷對應着一個 中斷號(中斷向量號),下面列表說明操作系統

中斷號 含義 來源 類型 是否有錯誤碼
0 divide error DIV and IDIV instructions Fault
1 debug any code or data reference Fault/Trap
2 NMI Interrupt NMI Interrupt
3 Breakpoint INT3 instruction Trap
4 Overflow INTO instruction Trap
5 bound range exceeded BOUND instruction Fault
6 invalid opcode UD2 instruction or reserved opcode.1 Fault
7 device not available floationg-point or WAIT/FWAIT instruction Fault
8 double fault any instruction that can generate an exception, an NMI, or an INTR Fault Y(0)
9 CoProcessor Segment Overrun Floating-point instruction.2 Fault
10 invalid TSS task switch or TSS access Fault Y
11 segment not present loading segment registers or accessing system segments Fault Y
12 stack segment fault stack operations and SS register loads Fault Y
13 general protection any memory reference and other protection checks Fault Y
14 page fault any memory reference Fault Y
15 reserved
16 floating-point error floating-point or WAIT/FWAIT instruction Fault
17 alignment check any data refrence in memory.3 Fault Y(0)
18 machine check error codes and source are model dependent.4 Fault
19 SIMD floating-point exception SIMD floating-point instruction5 Fault
20-31 reserved
32-255 maskable interrupts External Interrupt from INTR pin or INT n instruction Interrupt

5、中斷描述符表 IDT

咱們先來回顧一下上一講 【自制操做系統07】深刻淺出特權級 說的四種門描述符

type值 存在位置 用法
任務門 0101 GDT、LDT、IDT 與TSS配合實現任務切換,不過大多數操做系統都不這麼玩
中斷門 1110 IDT 進入中斷後屏蔽中斷(eflags的IF位置0),linux利用此實現系統調用,int 0x80
陷阱門 1111 IDT 進入中斷後不屏蔽中斷
調用門 1100 GDT、LDT 用戶用call或jmp指令從用戶進程進入0特權級

你看,正如上一講所說,中斷門進入後先是屏蔽了中斷,也就是中斷例程的 上半部,程序中能夠隨時打開中斷,也就天然到了 下半部,這就是 linux 系統的處理方式。debug

如何找到中斷描述符表呢?你猜的沒錯,正如找 段描述符表頁表 等同樣,有個 IDTR 寄存器存儲它的位置(0-15位是表界限,16-47位表示表基址),有個 lidt 指令負責加載 IDTR。經典作法,咱們見過太屢次了,就很少說啦,不理解的能夠從本系列開頭開始看喲。

6、中斷處理過程

上圖就表示了整個中斷處理的過程,不過還有幾處圖中沒有顯示

特權級檢查:CPL <= 門描述符DPL && CPL > 目標代碼段DPL

棧的處理:將 CS、EIP、EFLAGS、SS、ESP 寄存器的值壓入中斷處理程序使用的棧

7、8259A芯片

咱們以前說過,外部設備發出中斷信號,進入 CPU 的 INT 引腳上。但若是有多個外部設備近乎同時發送中斷信號,CPU 先處理哪個呢?未被處理的中斷信號又記錄在哪裏呢?這時候就須要有個 中間的代理設備 來負責這個事情。

這個代理設備叫作 可編程中斷控制器 PIC,其中 8259A 芯片是最多見的一種,咱們這裏把它的內部結構展現出來,因爲是硬件相關,就不展開細說了,但因爲以後要爲其進行編程,因此你們先有個印象。

8、中斷代碼實現

因爲到此篇幅過長,且中斷代碼的實現也是須要很大篇幅描述的,包括 可編程中斷控制器的初始化,IDT 的初始化,以及中斷例程代碼的編寫,因此將放在下一章進行講解。

【自制操做系統09】中斷的代碼實現

寫在最後:開源項目和課程規劃

若是你對自制一個操做系統感興趣,不妨跟隨這個系列課程看下去,甚至加入咱們,一塊兒來開發。

參考書籍

《操做系統真相還原》這本書真的贊!強烈推薦

項目開源

項目開源地址:https://gitee.com/sunym1993/flashos

當你看到該文章時,代碼可能已經比文章中的又多寫了一些部分了。你能夠經過提交記錄歷史來查看歷史的代碼,我會慢慢梳理提交歷史以及項目說明文檔,爭取給每一課都準備一個可執行的代碼。固然文章中的代碼也是全的,採用複製粘貼的方式也是徹底能夠的。

若是你有興趣加入這個自制操做系統的大軍,也能夠在留言區留下您的聯繫方式,或者在 gitee 私信我您的聯繫方式。

課程規劃

本課程打算出系列課程,我寫到哪以爲能夠寫成一篇文章了就寫出來分享給你們,最終會完成一個功能全面的操做系統,我以爲這是最好的學習操做系統的方式了。因此中間遇到的各類坎也會寫進去,若是你能持續跟進,跟着我一塊寫,必然會有很好的收貨。即便沒有,交個朋友也是好的哈哈。

目前的系列包括

相關文章
相關標籤/搜索