?? interrupt-handling_4.htm
字號:
flag,是為了避免Instruction tracing影響中斷的響應。隨后的IRET指令會從棧中的EFLAGS中恢復TF
flag的值。</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
Gate來處理一個Interrupt/Exception時,CPU會在將EFLAGS壓棧之后,清除EFLAGS寄存器的IF flag。清除IF
flag,是為了避免在當前ISR執行時受到其它Interrupts的影響。隨后的IRET指令會從棧中的EFLAGS中恢復IF flag的值。而通過Trap
Gate來處理Interrupt/Exception則不會影響IF
flag的設置。</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"><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">需要注意的是,在恢復EFLAGS的時候,只有CPL=0的時候,IOPL域才能夠被恢復;只有CPL在數值上小于或等于IOPL時,IF位才能夠被恢復。</SPAN></FONT></SPAN></SPAN></FONT></SPAN></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 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></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 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">下面是用C++實現的IRET指令:</SPAN></FONT></SPAN></SPAN></FONT></SPAN></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 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></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 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">inline
void iret(void)</SPAN></FONT></SPAN></SPAN></FONT></SPAN></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 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></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 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"> __asm__
__volatile__ ("iret": :
:"memory");</SPAN></FONT></SPAN></SPAN></FONT></SPAN></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 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></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 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></SPAN></FONT></SPAN></SPAN></FONT></SPAN> </P><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 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">
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><FONT size=4><STRONG>Task Gate</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"
align=left><FONT face=宋體><FONT face="Times New Roman TUR"><FONT
face=宋體></FONT></FONT></FONT> </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><FONT face=宋體><FONT face="Times New Roman TUR"><FONT
face=宋體>如果</FONT></FONT><FONT face="Times New Roman TUR">調用Task
Gate</FONT>,會引起<FONT face="Times New Roman TUR">Context</FONT>切換。如果<FONT
face="Times New Roman TUR">Interrupts/Exceptions</FONT>使用這種方式的話,會有如下幾個優點:</FONT></P><FONT
face=宋體>
<UL>
<LI>被中斷的程序的<FONT face="Times New Roman TUR">Context</FONT>會被完全被保存;
<LI>允許<FONT face="Times New Roman TUR">ISR</FONT>使用新的<FONT
face="Times New Roman TUR">CPL</FONT>為<FONT
face="Times New Roman TUR">0</FONT>的<FONT
face="Times New Roman TUR">stack</FONT>;這樣如果<FONT
face="Times New Roman TUR">Interrupt/Exception</FONT>是由于內核<FONT
face="Times New Roman TUR">stack</FONT>越界引起的話,可以通過<FONT
face="Times New Roman TUR">TSS</FONT>指定的新的<FONT
face="Times New Roman TUR">CPL=0</FONT>的<FONT
face="Times New Roman TUR">stack</FONT>來解決這個故障,而不是讓系統崩潰;
<LI>
<P><FONT
face="Times New Roman TUR">ISR</FONT>可以被放在一個獨立的地址空間中,這種情況下,你需要通過設定一個獨立的<FONT
face="Times New Roman TUR">LDT</FONT>。</P></LI></UL>
<P>但也必須注意它的缺點:由于在任務切換時,當時的機器狀態需要全部被保存,所以它的性能要比<FONT
face="Times New Roman TUR">Interrupt Gate</FONT>和<FONT
face="Times New Roman TUR">Trap Gate</FONT>低。從而導致中斷延遲越來越多。</P>
<DIV>將<FONT face="Times New Roman TUR">ISR</FONT>作為一個<FONT
face="Times New Roman TUR">Task</FONT>,然后通過<FONT face="Times New Roman TUR">Task
Gate</FONT>實現從被中斷任務向<FONT face="Times New Roman TUR">ISR
Task</FONT>的切換,與普通的任務切換沒有什么兩樣。我們注意到,在<FONT face="Times New Roman TUR">Task Gate
Descriptor</FONT>中,一個主要的元素就是</FONT><FONT face="Times New Roman TUR">TSS Segment
Selector</FONT><FONT face=宋體>,這個<FONT
face="Times New Roman TUR">Selector</FONT>指向一個存放在<FONT
face="Times New Roman TUR">GDT</FONT>中的<FONT face="Times New Roman TUR">TSS
Descriptor</FONT>。它所指向的<FONT face="Times New Roman TUR">TSS</FONT>是供<FONT
face="Times New Roman TUR">ISR Task</FONT>使用的。這個<FONT
face="Times New Roman TUR">TSS</FONT>中的<FONT face="Times New Roman TUR">Previous
Task Link</FONT>域指向那個被中斷任務的<FONT face="Times New Roman TUR">TSS</FONT>。如果<FONT
face="Times New Roman TUR">Exception</FONT>返回一個<FONT
face="Times New Roman TUR">error code</FONT>的話,那么<FONT
face="Times New Roman TUR">error code</FONT>會被保存在<FONT
face="Times New Roman TUR">ISR Task</FONT>的<FONT
face="Times New Roman TUR">stack</FONT>中。</FONT></DIV>
<P align=center><IMG src="interrupt-handling_4.files/task_gate.gif"
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/handling/task_gate.gif"></P>
<HR width="100%" SIZE=2>
<P><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN
style="mso-tab-count: 1"><FONT face="Times New Roman TUR"
size=5><STRONG>2.4.3 Task Restart</STRONG><SPAN lang=EN-US><FONT
face="Times New Roman" size=5><SPAN style="mso-tab-count: 1"> </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">為了能夠保證一個被中斷的Task能夠在ISR運行結束后繼續運行,除了Aborts之外的其他Exceptions,會保證在引起異常的精確指令位置來觸發這個Exception。而所有的Interrupts則保證在一個指令結束后才會被觸發。也就是說Interrupts/Exceptions都不會破壞指令的原子性。</FONT></FONT></FONT></FONT></SPAN></FONT></SPAN></P>
<P class=MsoNormal
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -