?? interrupt-handling_4.htm
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0063)http://www.huihoo.com/gnu_linux/own_os/interrupt-handling_4.htm -->
<HTML><HEAD><TITLE></TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2800.1106" name=GENERATOR></HEAD>
<BODY>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT
face="Times New Roman" size=6><SPAN style="mso-tab-count: 1"><STRONG>2.4
Handling & Error Code</STRONG></SPAN></FONT></SPAN></P><SPAN
lang=EN-US><FONT face="Times New Roman" size=5><SPAN style="mso-tab-count: 1">
<P>
<P><FONT size=3>[</FONT><A
href="index.htm"
tppabs="http://pagoda-ooos.51.net/os_book/index.htm"><FONT
size=3>Home</FONT></A><FONT size=3>] [</FONT><A
href="interrupt_and_exception.htm"
tppabs="http://pagoda-ooos.51.net/os_book/interrupt_and_exception.htm"><FONT
size=3>Top</FONT></A><FONT size=3>] [</FONT><A
href="interrupt-priority_3.htm"
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/interrupt-priority_3.htm"><FONT
size=3>Previous</FONT></A><FONT size=3>] [</FONT><FONT size=3><A
href="interrupt-8259_5.htm"
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/interrupt-handling_4.htm">Next</A>]</FONT></P>
<P><STRONG>
<HR width="100%" SIZE=2>
</STRONG>
<P></P>
<P></P></SPAN></FONT></SPAN><SPAN lang=EN-US><FONT face="Times New Roman"
size=5><SPAN style="mso-tab-count: 1">
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><FONT
face="Times New Roman TUR" size=5><STRONG>2.4.1 Overview</STRONG></FONT></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman" size=5><SPAN
style="mso-tab-count: 1"><FONT face=宋體><FONT size=3><FONT
face="Times New Roman TUR"></FONT></FONT></FONT></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman" size=5><SPAN
style="mso-tab-count: 1"><FONT face=宋體><FONT size=+0><FONT size=3><FONT
face="Times New Roman TUR">當一個Interrupt/Exception發生時,CPU將以這個Interrupt/Exception的Vector
Number為索引,到IDT中查找相應的Gate Descriptor。IDT中的Gate Descriptor有3種:Interrupt Gate
Descriptor,Trap Gate Descriptor,Task Gate Descriptor。根據被設置的Gate
Descriptor的不同,對ISR的調用方法和處理過程也不同。</FONT></FONT></FONT></FONT></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">當某些Exceptions發生時,會返回Error
Code,以通知相應的ISR是那個Segment引起了這個Exception。</SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><STRONG><FONT face="Times New Roman" size=5> </P>
<HR width="100%" SIZE=2>
</FONT></STRONG>
<P></P>
<P><STRONG><FONT face="Times New Roman" size=5></FONT></STRONG></P><SPAN
lang=EN-US><FONT face="Times New Roman" size=5><SPAN style="mso-tab-count: 1">
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><FONT
face="Times New Roman TUR"><STRONG>2.4.2 ISR Handling</STRONG></FONT></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman" size=5><SPAN
style="mso-tab-count: 1"><FONT face=宋體><FONT size=3><FONT
face="Times New Roman TUR"></FONT></FONT></FONT></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman" size=5><SPAN
style="mso-tab-count: 1"><FONT face=宋體><FONT size=+0><FONT size=3><FONT
face="Times New Roman TUR">一個ISR(Interrupt Service
Routine)是一塊專門用來處理某個Interrupt/Exception的程序。</FONT></FONT></FONT></FONT></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">如果一個Interrupt/Exception引用的是一個Interrupt Gate或Trap
Gate,則當這個Interrupt/Exception發生時,不發生任務切換,其ISR仍然引用當前任務的Context。Interrupt/Trap Gate
Descriptor中的Segment
Selector引用的是一個放在GDT或當前LDT中的可執行代碼段。Offset域引用的是其ISR的入口地址。</SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=center><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=center><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><IMG src="interrupt-handling_4.files/isr.gif"
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/handling/isr.gif"></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">當CPU調用一個ISR時,會將EFLAGS,CS,EIP寄存器壓棧,其中CS,EIP寄存器的內容事實上是ISR的返回地址。如果一個Exception發生時,存在一個Error
Code,那么這個Error Code會在EIP之后被壓棧。</SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">如果ISR和被打斷的任務具有相同的特權等級,則CPU不改變Stack,讓ISR繼續使用當前的Stack。</SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">如果ISR的特權等級從數字上小于被打斷任務的特權等級,也就是說如果ISR的權限大于被打斷任務的權限,則會發生Stack
Switch。為了能夠在ISR結束之后,能夠恢復使用原來的Stack,CPU會將SS和ESP寄存器的內容也壓棧,并且這些內容都被壓在新的Stack中,而不是Stack
Switch之前的那個Stack。</SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=center><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><IMG src="interrupt-handling_4.files/intr_stack.gif"
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/handling/intr_stack.gif"></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=center><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN
style="mso-tab-count: 1">問題是,CPU在Interrupt/Exception發生的時刻,發現特權等級不一致的時候,如何知道該使用那個棧?答案是通過當前任務的TSS。在TSS中存放著針對0,1,2三個特權等級的SS和ESP內容,當特權等級切換到某個特權等級的時候,CPU會從當前任務的TSS中找到相應特權等級的SS和ESP用來進行Stack
Switch。</SPAN></FONT></SPAN></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN
style="mso-tab-count: 1">當ISR執行結束之后,需要繼續執行之前被終止的任務,為了能夠正確的做到這一點,ISR的返回必須使用IRET指令。</SPAN></FONT></SPAN></SPAN></FONT></SPAN><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN
style="mso-tab-count: 1">IRET指令會自動從Stack中恢復EFLAGS寄存器的值,并根據Stack中的CS,EIP內容挑轉到被中斷的位置。</SPAN></FONT></SPAN></SPAN></FONT></SPAN><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1">如果之前在Interrupt/Exception發生的時候,進行了Stack
Switch,此時IRET會根據棧中的SS,ESP的內容將Stack切換回去。</SPAN></FONT></SPAN></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1">當通過一個Interrupt Gate或Trap
Gate來處理一個Interrupt/Exception時,CPU會在將EFLAGS壓棧之后,清除EFLAGS寄存器的TF flag。清除TF
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -