




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第五章中斷與異常中斷的基本知識中斷描述符表的初始化中斷處理中斷的下半部處理機制中斷的應用-時鐘中斷數據傳送控制方式選擇和衡量控制方式的原則:數據傳送速度足夠高系統開銷小,所需的處理控制程序少;能充分發揮硬件資源的能力;數據傳送控制方式程序直接控制方式中斷控制方式DMA方式通道方式ProgrammedDirectControl否外圍設備做接收或發送數據準備接收到start命令標志觸發器置“done”等待CPU來的下條指令準備完畢?是否CPU發start命令等待執行下條指令開始數據傳送設備標志觸發器為done”?是(a)(b)優點:控制簡單,不需要多少硬件支持缺點:1.CPU和外設只能串行工作;2.CPU在一段時間內只能和一臺外設交換數據,不能實現設備間的并行操作;3.無法發現和處理由于設備和其他硬件所產生的錯誤。Interrupt中斷控制方式的處理過程接收到CPU發來的start指令準備數據并將其置入緩沖寄存器緩沖寄存器滿嗎?控制器發中斷信號向設備發start指令將中斷允許位置1調度程序調度其他進程其他進程執行收到中斷信號了嗎?中斷處理被中斷進程執行否否是是設備CPU優點:并行操作缺點:1.I/O控制器的數據緩沖寄存器滿,就會發中斷。此寄存器一般較小,則在一次數據傳送過程中,中斷次數較多,將耗去大量CPU時間;若設備間并行操作,則中斷次數增加,造成CPU無法響應中斷和數據丟失。2.中斷方式是假設外設速度很低。如果外設速度很高,則造成CPU來不及取走數據緩沖寄存器中的數據,造成數據丟失。中斷控制的主要優點:CPU只有在I/O需要服務時才響應。外部中斷:外部設備所發出的I/O請求。內部中斷:也稱之為“異常”,是為解決機器運行時所出現的某些隨機事件及編程方便而出現的。<>中斷掠影中斷向量:8位無符號整數中斷源的編號0~255外設可屏蔽中斷:32~47屏蔽外部I/O請求
中斷線、IRQ異常及非屏蔽中斷:0~31異常:CPU內部中斷非屏蔽中斷:計算機內部硬件出錯引起的異常軟中斷:48~255中斷描述符表:描述中斷的相關信息中斷相關的匯編指令:<>5.1中斷的基本知識中斷向量-每個中斷源都被分配一個8位無符號整數作為類型碼,即中斷向量。(0~255)中斷的種類:中斷:外部可屏蔽中斷外部非屏蔽中斷異常:不使用中斷控制器,不能被屏蔽故障陷阱<>中斷向量-中斷源的類型Intelx86通過兩片中斷控制器8259A來響應15個外中斷源,每個8259A可管理8個中斷源。外部設備擁有相應權限時
,可以向特定的中斷線發送中斷請求信號IRQ。外部I/O請求的屏蔽:從CPU的角度,清除eflag的中斷標志位(關中斷)從中斷控制器的角度,將中斷屏蔽寄存器的相應位置位<>外設可屏蔽中斷
異常就是CPU內部出現的中斷,即在CPU執行特定指令時出現的非法情況。非屏蔽中斷就是計算機內部硬件出錯時引起的異常情況。
Intel把非屏蔽中斷作為一種異常來處理。在CPU執行一個異常處理程序時,就不再為其他異常或可屏蔽中斷請求服務。
<>異常及非屏蔽中斷
Intelx86處理器發布了大約20種異常(具體數字與處理器模式有關)。Linux內核必須為每種異常提供一個專門的異常處理程序。
<>異常及非屏蔽中斷中斷描述符表(IDT):即中斷向量表,每個中斷占據一個表項(門描述符,8字節)。<>中斷描述符表主要門描述符為:(1)中斷門(Interruptgate):類型碼為110,請求特權級(DPL)為0。
中斷門包含了一個中斷或異常處理程序所在段的選擇符和段內偏移量。(2)陷阱門(Trapgate):類型碼為111,與中斷門類似,其唯一的區別是,不關中斷。(3)系統門(Systemgate):Linux內核特別設置的,用來讓用戶態的進程訪問Intel的陷阱門,DPL為3。系統調用就是通過系統門進入內核的。中斷描述符表寄存器IDTR:存放中斷描述符表在內存的起始地址。中斷描述符表寄存器IDTR是一個48位的寄存器,其低16位保存中斷描述符表的大小,高32位保存中斷描述符表的基址。中斷描述符表調用過程指令CALL:CALL過程名調用中斷過程的指令INT
INT中斷向量(0~255)中斷返回指令IRETIRET
加載中斷描述符表的指令LIDT
LIDT48位的偽描述符<>相關匯編指令
Linux內核在系統的初始化階段要初始化可編程控制器8259A;將中斷描述符表的起始地址裝入IDTR寄存器,并初始化表中的每一項。
當計算機運行在實模式時,中斷描述符表被初始化,并由BIOS使用。真正進入了Linux內核,中斷描述符表就被移到內存的另一個區域,并為進入保護模式進行預初始化:用匯編指令LIDT對中斷向量表寄存器IDTR進行初始化,即把IDTR置為0;把中斷描述符表IDT的起始地址裝入IDTR;setup_idt()函數填充中斷描述表中的256個表項。<>5.2中斷描述符表的初始化IDT表項的設置通過_set_gate()函數實現
調用該函數在IDT表中插入一個中斷門:voidset_intr_gate(unsignedintn,void*addr){_set_gate(idt_table+n,14,0,addr);}調用該函數在IDT表中插入一個陷阱門:staticvoid__init
set_trap_gate(unsignedintn,void*addr){_set_gate(idt_table+n,15,0,addr);}調用該函數在IDT表中插入一個系統門:staticvoid__initset_system_gate(unsignedintn,void*addr){_set_gate(idt_table+n,15,3,addr);}<>IDT表項的設置trap_init()函數用于設置中斷描述符表開頭的19個陷阱門和系統門。這些中斷向量都是CPU保留用于異常處理的,例:set_trap_gate(0,÷_error);set_trap_gate(1,&debug);set_trap_gate(19,&simd_coprocessor_error);set_system_gate(SYSCALL_VECTOR,&system_call);
<>初始化陷阱門和系統門中斷門的設置是由init_IRQ()函數中的一段代碼完成的:設置時必須跳過用于系統調用的向量0x80
中斷處理程序的入口地址是一個數組interrupt[],數組中的每個元素是指向中斷處理函數的指針。
<>中斷門的設置for(i=0;i<NR_IRQS;i++){intvector=FIRST_EXTERNAL_VECTOR+i;if(vector!=SYSCALL_VECTOR)set_intr_gate(vector,interrupt[i]);}中斷和異常的硬件處理:從硬件的角度看CPU如何處理中斷和異常中斷請求隊列的建立:方便外設共享中斷線
中斷處理程序的執行
從中斷返回:調用恢復中斷現場的宏RESTORE_ALL,徹底從中斷返回
<>5.3中斷處理當CPU執行了當前指令之后,CS和EIP這對寄存器中所包含的內容就是下一條將要執行指令的虛地址。在對下一條指令執行前,CPU先要判斷在執行當前指令的過程中是否發生了中斷或異常。如果發生了一個中斷或異常,那么CPU將做以下事情:<>中斷和異常的硬件處理
確定所發生中斷或異常的向量i(在0~255之間)通過IDTR寄存器找到IDT表,讀取IDT表第i項(或叫第i個門)分“段”級、“門”級兩步進行有效性檢查檢查是否發生了特權級的變化
中斷和異常處理中CPU的工作SSESPEFLAGSCSEIPERRORCODEEFLAGSCSEIPERRORCODE堆棧增長方向中斷發生前夕的SS:ESP返回地址錯誤碼<>中斷處理程序堆棧由于硬件條件的限制,很多硬件設備共享一條中斷線。為方便處理,Linux為每條中斷線設置了一個中斷請求隊列。中斷服務例程與中斷處理程序中斷線共享的數據結構注冊中斷服務例程<>中斷請求隊列的建立中斷服務例程(InterruptServiceRoutine):每個中斷請求都有自己單獨的中斷服務例程。中斷處理程序:共享同一條中斷線的所有中斷請求有一個總的中斷處理程序。在Linux中,15條中斷線對應15個中斷處理程序。<>中斷服務例程與中斷處理程序
structirqaction{void(*handler)(int,void*,structpt_regs*);unsignedlongflags;unsignedlongmask;constchar*name;void*dev_id;structirqaction*next;};
Handler:指向一個具體I/O設備的中斷服務例程Flags:用一組標志描述中斷線與I/O設備之間的關系。SA_INTERRUPT:中斷處理程序執行時必須禁止中斷SA_SHIRQ:允許其它設備共享這條中斷線。SA_SAMPLE_RANDOM:內核可以用它做隨機數產生器。SA_PROBE:內核正在使用這條中斷線進行硬件設備探測。<>中斷線共享的數據結構
<>structirqaction{void(*handler)(int,void*,structpt_regs*);unsignedlongflags;unsignedlongmask;constchar*name;void*dev_id;structirqaction*next;};
Name:I/O設備名dev_id:指定I/O設備的主設備號和次設備號(參見第9章)。Next:指向irqaction描述符鏈表的下一個元素
中斷線共享的數據結構
初始化IDT表之后,必須通過request_irq()函數將相應的中斷服務例程掛入中斷請求隊列,即對其進行注冊。
在關閉設備時,必須通過調用free_irq()函數釋放所申請的中斷請求號。
<>注冊中斷服務例程
int
request_irq(unsigned
int
irq,void(*handler)(int,void*,struct
pt_regs*),unsignedlongirqflags,constchar*devname,void*dev_id)假定一個程序要對/dev/fd0/(第一個軟盤對應的設備)設備進行訪問,通常將IRQ6分配給軟盤控制器,給定這個中斷號6,軟盤驅動程序就可以發出下列請求,以將其中斷服務例程掛入中斷請求隊列:
request_irq(6,floppy_interrupt, SA_INTERRUPT|SA_SAMPLE_RANDOM,"floppy",NULL);
注冊中斷服務例程
所有的中斷處理程序都執行四個基本的操作:在內核棧中保存IRQ的值和寄存器的內容。給與IRQ中斷線相連的中斷控制器發送一個應答,這將允許在這條中斷線上進一步發出中斷請求。執行共享這個IRQ的所有設備的中斷服務例程(ISR)。跳到ret_from_intr()的地址后終止。<>中斷處理程序的執行
CPU從中斷控制器的一個端口取得中斷向量I
根據I從中斷描述符表IDT中找到相應的中斷門從中斷門獲得中斷處理程序IRQn_interrupt的入口地址
判斷是否要進行堆棧切換調用do_IRQ()對所接收的中斷進行應答,并禁止這條中斷線調用handle_IRQ_event()來運行對應的中斷服務例程-處理最緊急的任務。
<>中斷處理程序的執行
IRQn_interrupt:pushl$n-256jmpcommon_interruptcommon_interrupt:SAVE_ALLcalldo_IRQjmpret_from_intrdo{status|=action->flags;action->handler(irq,action->dev_id,regs);action=action->next;}while(action);
當處理所有外設中斷請求的函數do_IRQ()執行時,內核棧頂包含的就是do_IRQ()的返回地址,這個地址指向ret_from_intr。從中斷返回時,CPU要調用恢復中斷現場的宏RESTORE_ALL,徹底從中斷返回。
<>從中斷返回中斷服務例程在中斷請求關閉的條件下執行,避免嵌套使中斷控制復雜化。
系統不能長時間關中斷運行,因此內核應盡可能快的處理完中斷請求,盡其所能把更多的處理向后推遲。內核把中斷處理分為兩部分:上半部(tophalf)和下半部(bottomhalf),上半部內核立即執行,而下半部留著稍后處理。
<>5.4中斷的下半部處理機制
為什么把中斷分為兩部分來處理?一個快速的“上半部”來處理硬件發出的請求,它必須在一個新的中斷產生之前終止。這一部分做的工作很少。下半部運行時是允許中斷請求的,而上半部運行時是關中斷的,這是二者之間的主要區別。Linux內核下半部的實現機制在內核的演變:bottomhalf(簡稱bh)在2.4以后的版本:小任務(tasklet)下半部可以在多處理機上并行執行,并有助于驅動程序的開發者進行驅動程序的開發。
為什么把中斷分為兩部分來處理下半部是一個不能與其他下半部并發執行的高優先級小任務。
bh_base是一個指向下半部的指針數組,用于組織所有下半部
bh_base數組共有32項,每一項都是一種下半部。<>下半部
下半部外部設備TIMER_BH定時器TQUEUE_BH
周期性任務隊列SERIAL_BH
串行端口IMMEDIATE_BH
立即任務隊列Linux常用的下半部一個函數指針數組bh_base[],它把所有的后半部分都組織起來,其大小為32,數組中的每一項就是一個后半部分,即一個bh函數。設置了兩個32位無符號整數bh_active和bh_mask,每個無符號整數中的一位對應著bh_base[]中的一個元素。在2.4以前的內核中,每次執行完do_IRQ()中的中斷服務例程以后,以及每次系統調用結束之前,就在一個叫do_bottom_half()的函數中執行相應的bh函數。在do_bottom_half()中對bh函數的執行是在關中斷的情況下進行的,這是因為,對單CPU來說,bh函數的執行可以不嵌套;而對于多CPU來說,在同一時間內最多只允許一個CPU執行bh函數。那么,在新內核的設計中,是改進bh機制還是拋棄bh機制,建立一種新的機制?2.4選擇了一種折中的辦法,繼續保留bh機制,另外增加一種或幾種機制,并把它們納入一個統一的框架中,這就是2.4內核中的軟中斷(softirq)機制。軟中斷機制:軟中斷卻在任何時候都不需要串行化。Tasklet機制:建立在軟中斷之上,同一個tasklet只能運行在一個CPU上,而不同的tasklet可以同時運行在不同的CPU上。在這種情況下,tasklet就不需要是可重入的,因此,編寫tasklet比編寫一個軟中斷要容易。
Bh機制在2.4中依然存在,但不是作為一個單獨的機制存在,而是建立在tasklet之上。因此,在2.4版中,設備驅動程序的開發者必須更新他們原來的驅動程序,用tasklet代替bh。下半部
小任務是指待處理的下半部,其數據結構為tasklet_struct,每個結構代表一個獨立的小任務。小任務既可以靜態地創建,也可以動態地創建。
<>小任務機制
structtasklet_struct{Structtasklet_struct*next;unsignedlongstate;atomic_tcount; void(*func)(unsignedlong);unsignedlongdata; };
如果準備靜態地創建一個小任務(也就是對它直接引用),使用下面兩個宏中的一個:DECLARE_TASKLET(name,func,data)DECLARE_TASKLET_DISABLED(name,func,data)這兩個宏都能根據給定的名字靜態地創建一個tasklet_struct結構。第一個宏把創建的小任務的引用計數器設置為0,因此,該小任務處于激活狀態。另一個把引用計數器設置為1,所以該小任務處于禁止狀態。例如:DECLARE_TASKLET(my_tasklet,my_tasklet_handler,dev);這行代碼其實等價于structtasklet_structmy_tasklet={NULL,0,ATOMIC_INIT(0),tasklet_handler,dev};聲明和使用小任務voidtasklet_handler(unsignedlongdata)小任務不能睡眠,不能在小任務中使用信號量或者其它產生阻塞的函數。但它運行時可以響應中斷。通過調用tasklet_schedule()函數并傳遞給它相應的tasklet_struct指針,該小任務就會被調度以便適當的時候執行:tasklet_schedule(&my_tasklet)在小任務被調度以后,只要有機會它就會盡可能早的運行。調用tasklet_disable()函數來禁止某個指定的小任務。tasklet_disable(&my_tasklet);調用tasklet_enable()函數可以激活一個小任務。tasklet_enable(&my_tasklet); 可以調用tasklet_kill()函數從掛起的隊列中去掉一個小任務。<>編寫并調度自己的小任務任務隊列就是指以雙向隊列形式連接起來的任務鏈表,每一個鏈表元素都描述了一個可執行的內核任務。tq_struct來描述任務隊列中的每一個鏈表成員。三個特殊的任務隊列:tq_immediate任務隊列,由IMMEDIATE_BH下半部運行,該隊列中包括要執行的內核函數和標準的下半部。
tq_timer任務隊列,由TQUEUE_BH下半部運行,每次時鐘中斷都激活這個下半部。tq_disk任務隊列,用于塊設備任務。<>任務隊列大部分PC機中有兩個時鐘源,分別是實時時鐘(RTC)和操作系統(OS)時鐘。實時時鐘也叫硬件時鐘,它靠電池供電,即使系統斷電,也可以維持日期和時間。RTC和OS時鐘之間的關系通常也被稱作操作系統的時鐘運作機制。不同的操作系統,其時鐘運作機制也不同。
<>5.5中斷的應用-時鐘中斷時鐘運作機制OS時鐘是由可編程定時/計數器產生的輸出脈沖觸發中斷而產生的。操作系統的“時間基準”由設計者決定,Linux的時間基準是1970年1月1日凌晨0點。OS時鐘記錄的時間就是系統時間。系統時間以“時鐘節拍”為單位。Linux中用全局變量jiffies表示系統自啟動以來的時鐘節拍數目。每次時鐘中斷jiffies就加1.
<>Linux時間系統每一次時鐘中斷的產生都觸發下列幾個主要的操作:自系統啟動以來所花費的時間加1更新時間和日期確定當前進程在CPU上已運行了多長時間,如果已經超過了分配給它的時間,則搶占它更新資源使用統計數檢查定時器時間間隔是否已到,如果是,則調用適當的函數
<>時鐘中斷處理程序時鐘中斷處理程序本身來完成通過TIMER_BH和TQUEUE_BH下半部調用的函數來完成timer_bh()函數與TIMER_BH下半部相關聯,它在每個時鐘節拍都被激活。
TIMER_BH下半部以關中斷調用update_times()函數,該函數會以關中斷來更新xtime。更新了系統時鐘xtime之后,update_times()再次打開中斷。時鐘中斷的下半部處理<>定時器是管理內核所花時間的基礎,也被稱為動態定時器或內核定時器。
定時器的使用:執行一些初始化工作,設置一個到期時間,指定
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年中國真絲絨毯行業投資前景及策略咨詢報告
- 2025至2030年中國捕煙氣閥市場分析及競爭策略研究報告
- 2025至2030年中國前緩沖塊市場分析及競爭策略研究報告
- 2024至2030年中國高強度鋁合金型材行業投資前景及策略咨詢研究報告
- 2024至2030年中國彈性體改性瀝青防水卷材市場調查研究報告-市場調查研究報告-市場調研
- 2024年中國白酒增香劑數據監測報告
- 行政批復協議書范本
- 船塢甲板加工合同協議
- 裝修施工合同安全協議
- 蘇州種菜承包合同協議
- 國家能源集團陸上風電項目通 用造價指標(2024年)
- 【MOOC】跨文化交際-蘇州大學 中國大學慕課MOOC答案
- 北師大版數學八年級下冊全冊教案及反思
- MOOC 國際商務-暨南大學 中國大學慕課答案
- 陜2022TJ 067 廚衛裝配式鋼絲網混凝土排氣道系統建筑構造圖集
- SQ-02-綠色食品種植產品調查表0308
- 視頻結構化大數據平臺解決方案
- 麗聲北極星分級繪本第二級上Dinner for a Dragon 教學設計
- 活躍氣氛的開場小游戲「培訓破冰前必備」
- 光伏發電項目安全專項投資估算方案
- 上海證券交易所(課堂PPT)
評論
0/150
提交評論