实模式向保护模式跳转
不知道能不能把这个问题说清楚,我是被这个东西搞得很头晕,虽然原理听上去还不算难,但是,想把它真的弄得很透彻真的很不容易,下面
,我就试着把自己的思路顺一下:
一:我们知道机器从加电到引导系统这过程,首先是工作在实模式下的,也就是按实地址方式寻址。寻址空间也只能达到1M,(因为只有20位地址线,所以只可以寻址到2的20次方)而到了386时代,地址线已经达到了32位,所以不用分段分页机制下的独立寻址空间已经达到了4GB,(这个数字不难得到吧^_^),现代操作系统,比方说WINDOWS都是工作在这种方式下的,而要想得到这么强的寻址能力,显然,我们的8086汇编课本上没有教你怎么做,物理地址=段值*16+偏移,的时代已经一去不回来了,所以才有了保护模式,至于为什么叫保护模式,可能会有很多的理由,但是我想只要把特权级说出来,大家就可以很想当然的理解为出于安全的分级管理。所以,我们要做的工作就是完成,这一跳转!
二:那么在保护模式下又是怎么寻址的呢,很明显,还是会用到几个段寄存器,在这里它们并不是直接的表示为段的地址,而是换了个名字叫做选择子,故名思意,它的意思是,通过段寄存器,就可以找到相应段的入口,和以前一样嘛,呵呵,但是在哪里选呢,于是又加了这样一个数据结构GDT(全局描述符表)每个描述符项都是一个特定的数据结构,里面记录了该段的基址,界限,访问权限等信息。那么这个GDT又是放在哪里的呢,还能放在哪,寄存器无疑是最理想的空间,快,准,稳嘛!还有寄存器啊?对,就是寄存器多,于是又来了一个专门用于放置GDT的寄存器,gdtr,那每一个段都会在这里登记下来它所处的位置,即添加关于它的描述符项,然后再定义一个选择子,(其实就是相对于GDT表最顶部的相对位移),这样就可以由这个选择子找到这个段的入口,从而达到跳转的目的。
三:所以我们可以这样做:
1:定义GDT段,准备GDT表;
2:定义个数据,代码及堆栈段;
3:为相应的段定义段选择子;
4:用lgdt指令加载gdtr;
5:打开A20地址线(这是历史的原因,因为开机以后20位地址线是没有打开的,需要手动打开才可以用)
6:置cr0的PE位(这是一个控制寄存器,此位置1则可以启用保护模式)
7:跳转,进入保护模式;(怎么跳?jmp,很好用的)
四:但是在跳的过程中,可能会遇到很多问题,Privilege,还有16位地址和32位地址不能直接跳等问题也很难。
而且,我们不能只跳过去,还要想到怎么才能跳出来,也就是怎么样才能再从保护模式跳回到实模式。
下面,我一边默写代码,一边回忆这样一个过程,大家可以从下面的代码里很好的理解我上面的思想。
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
下面是我们Intel Architecture中看到的有关于保护模式的文档,先来看这个图:
![](/images/cnblogs_com/stonecrazyking/segmentationpage.jpg)
这个图很清楚的说明了我刚才提到的GDT是如何工作的,这里并没有LDT,但是有LinearAdress,和PhysicalAddress,关于三种地址的转换问题,我会在下一讲里谈到,其实上面也就是我们在操作系统课里强调最多段页式存储。在这里,你会看得更清楚,因为你懂得了它的原理!甚至我们都用代码实现了!爽吧!
好了,时间不早了,我要睡了,可能今天对这个问题还没有吃透,明天继续,看来,我用自己的语言把这个东西说一遍真的印象加深了很多,而且,本来以为懂的东西,结果还是很糊涂,本来看不下去的大段英文,现在想用自己的语言表达,力求精确的时候,我又不得不仔细的读它,看来,这样学习,还真是个好方法,您不妨试试,或许我们还可以多多交流!晚安!