在x86系统的处理器中,8086,80286采用的都是基于段式的寻址方式,不同的地方在于8086只支持实地址模式,而在80286中增加了保护地址模式。
当时的段式寻址的过程是:
1)根据指令类型,获取对应的,代码段、数据段等,的段寄存器内容。
2)根据段寄存器的内容,找到相应的“地址段描述结构”。
3)从地址段描述结构中得到基地址。
4)完成规定的权限检查后,将指令中发出的地址作为位移,与基地址相加而得出实际的“物理地址”
在80386中对段式寻址做了补充,增加了两个新寄存器:一个是全局性的段描述表寄存器GDTR,另一个是局部性的段描述附表寄存器LDTR,分别用来指向存储在内存中的一个段描述结构数组。同时此时的段寄存器内容做出了改变,不在存放基地址,而是存放实际段描述结构的位置在段描述结构数组中的偏移。
此时上述的流程中取得地址段描述结构的流程变为:首先从相应的段寄存器中获取index,然后从GDTR或LDTR中获取段描述结构数组的地址,两者相结合从而获取最终段描述结构的地址,从而完成整个流程。
但在后来,段式的内存管理方式相对于页式内存管理存在着不小的差距,但同时为了保持处理器的向前兼容性,因此Intel最终决定在段式内存管理的基础上实现页式内存管理,即对于每一个地址必须首先经过段式内存的映射,最后还要经过页式内存的映射。
此时,经过段式内存映射的地址,即上文提到的“物理地址”就变成了新方式中的线性地址,最终经过页式内存映射的地址才是最后的物理地址。
这样的寻址方式是Intel x86系统处理器所特有的,但linux为了满足x86体系的要求,必须也要同时使用两种寻址机制。
但在具体的实现过程中,linux内核采用了比较取巧的方式,linux将每一个段描述结构中的基地址都改为0,而偏移量都改为4G,那么对于每一个段都是从0地址开始的整个4GB虚存空间,虚拟地址到线性地址的映射保持原值不变。因此在讨论或理解linux内核的地址映射时,可以直接将线性地址当做虚拟地址,二者完全一致。
这个时候,linux系统中三种地址的关系就比较清晰了,虚拟地址,线性地址,物理地址~~~
阅读(2206) | 评论(0) | 转发(0) |