⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 booting-protecte_mode_7.htm

📁 编写自己的操作系统
💻 HTM
📖 第 1 页 / 共 5 页
字号:
&nbsp;# base address = 0<BR>&nbsp;.word&nbsp;0x9200&nbsp;&nbsp;&nbsp;&nbsp; # 
data read/write<BR>&nbsp;.word&nbsp;0x00CF&nbsp;&nbsp;&nbsp;&nbsp;# granularity 
= 4096, 
386<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp; 
(+5th nibble of limit)</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></SPAN>&nbsp;</P><SPAN lang=EN-US>
<HR width="100%" SIZE=2>

<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><STRONG></STRONG><SPAN lang=EN-US><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><STRONG>1.7.3&nbsp;Load 
GDT</STRONG></FONT></SPAN></P><SPAN lang=EN-US><FONT face="Times New Roman" 
size=3>
<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></SPAN>&nbsp;</P></FONT></SPAN></SPAN></SPAN>
<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>设置好GDT之后,我们需要通过LGDT指令将设定的gdt的入口地址和gdt表的大小装入GDTR寄存器。</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></SPAN>&nbsp;</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>GDTR寄存器包括两部分:32-bit的线性基地址,以及16-bit的GDT大小(以字节为单位)。需要注意的是,对于32-bit线性基地址,必须是32-bit绝对物理地址,而不是相对于某个段的偏移量。而我们在Booting阶段,在进入Protected 
Mode之前,我们CS和DS设置很可能不是0,所以我们必须计算出gdt的绝对物理地址。</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></SPAN>&nbsp;</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>为了执行LGDT指令,你需要把这两部分内容放在内存的某个位置,然后将这个位置的内存地址作为操作数传递给LGDT指令。然后LGDT指令会自动将保存在这个位置的这两部分值装入GDTR寄存器。</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></SPAN>&nbsp;</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></SPAN>&nbsp;</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>#</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># 这是存放GDTR所需的两部分内容的位置</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>#</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>gdt_48:<BR>&nbsp;.word&nbsp;0x8000&nbsp;&nbsp;&nbsp;&nbsp;# gdt 
limit=2048,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp; 256 GDT entries</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;.word&nbsp;0, 
0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # gdt base (filled in 
later)</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></SPAN>&nbsp;</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>#</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># 下面这段代码用来计算GDT的32-bit线性地址,并将其装入GDTR寄存器。</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>#</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
xorl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %eax, %eax&nbsp;&nbsp;&nbsp;# Compute 
gdt_base<BR>&nbsp;movw&nbsp; &nbsp;%ds,&nbsp; %ax&nbsp;&nbsp;&nbsp; &nbsp;# 
(Convert %ds:gdt to a linear 
ptr)<BR>&nbsp;shll&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$4, 
%eax<BR>&nbsp;addl&nbsp;&nbsp;&nbsp;&nbsp; $gdt, 
%eax<BR>&nbsp;movl&nbsp;&nbsp;&nbsp; %eax, 
(gdt_48+2)<BR>&nbsp;lgdt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
gdt_48&nbsp;&nbsp;&nbsp;&nbsp;# load gdt with whatever is appropriate</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></SPAN>&nbsp;</P><SPAN lang=EN-US>
<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></SPAN>&nbsp;</P><SPAN lang=EN-US>
<HR width="100%" SIZE=2>

<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><STRONG></STRONG><SPAN lang=EN-US><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><STRONG>1.7.4&nbsp;其它准备</STRONG></FONT></SPAN></P><SPAN lang=EN-US><FONT 
face="Times New Roman" size=3>
<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></SPAN>&nbsp;</P></FONT></SPAN></SPAN></SPAN>
<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>在进入Protected Mode之前,除了需要设置和装入GDT之外,还需要做如下一些事情:</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></SPAN>&nbsp;</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>1、屏蔽所有可屏蔽中断;</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>2、装入IDTR;</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>3、所有协处理器被正确的Reset。</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></SPAN>&nbsp;</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>由于在Real Mode和Protected Mode下的中断处理机制有一些不同,所以在进入Protected 
Mode之前,务必禁止所有可屏蔽中断,这可以通过下面两种方法之一:</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></SPAN>&nbsp;</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>1、使用CLI指令;</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>2、对8259A可编程中断控制器编程以屏蔽所有中断。</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></SPAN>&nbsp;</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>即使当我们进入Protected Mode之后,也不能马上将中断打开,这时因为我们必须在OS Kernel中对相关的Protected 
Mode中断处理所需的数据结构正确的初始化之后,才能打开中断,否则会产生处理器异常。</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></SPAN>&nbsp;</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>在Real Mode下,中断处理使用IVT(Interrupt Vector Table),在Protected 
Mode下,中断处理使用IDT(Interrupt Descriptor Table),所以,我们必须在进入Protected 
Mode之前设置IDTR。</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></SPAN>&nbsp;</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>IDTR的格式和GDTR相同,IDTR的装入方式和GDTR也相同。由于IDT中相关的中断处理程序需要让OS 
Kernel来设定,所以在Booting阶段,我们只需要将IDTR中IDT的基地址和Size都设为0就可以了,随后,等进入Protected 
Mode之后,由OS Kernel来真正设置它。</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></SPAN>&nbsp;</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>关于中断机制和中断处理,请参考&nbsp;<A 
href="interrupt_and_exception.htm" 
tppabs="http://pagoda-ooos.51.net/os_book/interrupt_and_exception.htm">Interrupt 
&amp; Exception</A>&nbsp;,这里不再赘述。</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></SPAN>&nbsp;</P><SPAN lang=EN-US>
<P class=MsoNormal 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -