📄 interrupt-vectors_2.htm
字号:
face="Times New Roman TUR">Array</FONT>。每一个<FONT face="Times New Roman TUR">Gate
Descriptor</FONT>由<FONT face="Times New Roman TUR">8</FONT>个字节组成。每一个<FONT
face="Times New Roman TUR">Gate Descriptor</FONT>对应一个<FONT
face="Times New Roman TUR">Interrupt/Exceptions Vector</FONT>。由于最多可能存在<FONT
face="Times New Roman TUR">256</FONT>个<FONT
face="Times New Roman TUR">Vectors</FONT>,所以你完全没有必要创建包含多于<FONT
face="Times New Roman TUR">256</FONT>个<FONT face="Times New Roman TUR">Gate
Descriptor</FONT>的<FONT
face="Times New Roman TUR">IDT</FONT>(当然你那么做不会引起错误,但却造成了浪费)。但你可以创建少于<FONT
face="Times New Roman TUR">256</FONT>个<FONT face="Times New Roman TUR">Gate
Descriptor</FONT>的<FONT
face="Times New Roman TUR">IDT</FONT>,如果你根本不需要用到那么多的话。但一旦你创建了一个<FONT
face="Times New Roman TUR">IDT</FONT>,但<FONT
face="Times New Roman TUR">IDT</FONT>中的某些<FONT face="Times New Roman TUR">Gate
Descriptor你没有用到的话,你必须将其present flag清除,否则会造成异常或错误。</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"> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><FONT
face=宋体><FONT face="Times New Roman TUR">IDT</FONT>可以放在<FONT
face="Times New Roman TUR">RAM</FONT>的任何位置,但你必须将它的起始位置的线形地址(<FONT
face="Times New Roman TUR">base,32-bit</FONT>),以及它的大小(<FONT
face="Times New Roman TUR">limit, 16-bit</FONT>)放到寄存器<FONT
face="Times New Roman TUR">IDTR</FONT>中。这样,<FONT
face="Times New Roman TUR">CPU</FONT>才能够通过<FONT
face="Times New Roman TUR">IDTR</FONT>知道<FONT
face="Times New Roman TUR">IDT</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"><FONT
face=宋体><FONT face="Times New Roman TUR"></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">当我们设置IDT的位置时,我们最好能将其起始位置按照8对齐,这样可以让CPU对IDT的存取性能最高。</P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><FONT
face=宋体><FONT face="Times New Roman TUR">IDTR</FONT>寄存器长度为<FONT
face="Times New Roman TUR">48 bits</FONT>,包括<FONT
face="Times New Roman TUR">32-bit base address</FONT>和<FONT
face="Times New Roman TUR">16-bit limit</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=center><IMG src="interrupt-vectors_2.files/idt.gif"
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/vectors/idt.gif"></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">LIDT</FONT>和</FONT><FONT
face="Times New Roman TUR">SIDT</FONT><FONT face=宋体>指令可以操作<FONT
face="Times New Roman TUR">IDTR</FONT>寄存器。<FONT
face="Times New Roman TUR">LIDT(Load IDTR Register)</FONT>可以将<FONT
face="Times New Roman TUR">IDTR</FONT>寄存器的<FONT face="Times New Roman TUR">Base
address</FONT>和<FONT face="Times New Roman TUR">Limit</FONT>装入<FONT
face="Times New Roman TUR">IDTR</FONT>寄存器,这个<FONT
face="Times New Roman TUR"><FONT face=宋体>指令只能在</FONT>CPL(Current Privilege Level
)<FONT face=宋体>为0,也就是说当前<FONT face="Times New Roman TUR">Privilege
Level</FONT>必须为特权等级的</FONT></FONT><FONT
face="Times New Roman TUR">情况下被执行。SIDT(Store IDTR Register)</FONT>可以将<FONT
face="Times New Roman TUR">IDTR</FONT>寄存器的内容读出并存储到某个<FONT
face="Times New Roman TUR">RAM</FONT>位置,这个指令可以在任何<FONT
face="Times New Roman TUR">Privilege Level下被执行。</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> </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>如果一个程序引用的Vector Number超过了IDTR中设置的IDT Limit,一个General-protection
Exception会被触发。</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> </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>我们可以用下列C++代码来实现这两个指令:</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> </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>typedef unsigned long addr_t;</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>typedef unsigned long slimit_t;</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> </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>inline void lidt(addr_t __base, slimit_t __limit) </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>{<BR> unsigned long __tmp[2];<BR><BR>
__tmp[0] = __limit << 16;<BR> __tmp[1] = (unsigned
int)__base;<BR> __asm__ ("lidt (%0)": :"p" (((char *)
__tmp)+2));</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>}<BR></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>inline void sidt(addr_t& __base, slimit_t& __limit)</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>{<BR> unsigned long
__tmp[2];<BR> </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> __asm__
("sidt (%0)": :"p" (((char *) __tmp)+2));</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>
memcpy((void*)&__base, (void*)&__tmp[1], 4);</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>
memcpy((void*)&__limit, (void*)(((char*) __tmp)+2), 2);</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>}<BR></P>
<P><STRONG>
<HR width="100%" SIZE=2>
<P></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"></STRONG> <FONT
size=5><STRONG>2.2.4 IDT Descriptors</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> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><FONT
face=宋体>在<FONT face="Times New Roman TUR">IDT</FONT>中,可以包含如下<FONT
face="Times New Roman TUR">3</FONT>种类型的</FONT><FONT
face="Times New Roman TUR">Descriptor</FONT><FONT face=宋体>:</FONT></P>
<UL>
<LI>Task-gate descriptor
<LI>Interrupt-gate descriptor
<LI>Trap-gate descriptor</LI></UL>
<P align=center><IMG src="interrupt-vectors_2.files/idt_desc.gif"
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/vectors/idt_desc.gif"></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>Interrupts/Exceptions应该使用Interrupt Gate<FONT face=宋体>和</FONT>Trap
Gate<FONT face=宋体>,它们之间的唯一区别就是:当调用<FONT face="Times New Roman TUR">Interrupt
Gate</FONT>时,<FONT face="Times New Roman TUR">Interrupt</FONT>会被<FONT
face="Times New Roman TUR">CPU</FONT>自动禁止;而调用<FONT
face="Times New Roman TUR">Trap Gate</FONT>时,<FONT
face="Times New Roman TUR">CPU</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> </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="Times New Roman TUR">Task
Gate一种通过硬件实现任务切换,将ISR作为一个Task的方法,我们在处理Interrupts/Excetpions的时候,通常不会用到这种方法。</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> </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>由于Gate Descriptor是由2个32-bit字长的部分组成,我们可以定义:</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> </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>struct descriptor_s{</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> unsigned long low_dw;</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> unsigned long high_dw;</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>};</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> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -