linux中为什么要有分段和分页机制

来源:互联网 发布:手机分析软件 编辑:程序博客网 时间:2024/04/28 19:12
linux中为什么要有分段和分页机制
 
首先讲述linux系统上的实模式和保护模式是指什么。为什么要分实模式和保护模式呢?他们当中有什么区别呢?
 
首先实模式和保护模式是CPU的两种工作模式。一开始PC启动时CPU是工作在实模式下的,经过某种机制后,CPU跳转到保护模式。其访问空间扩大了,要想从保护模式返回到实模式就只能重启。
Intel 8086是16位CPU,它只有16位寄存器、16位数据总线和20位地址总线,它只能运行在实模式
在实模式,
物理地址=段值*16+偏移 
段值和偏移都是16位的 具有1MB(2^16 * 2^4 + offset)的寻址能力。
 
而从80386开始CPU有32位地址线,所以寻址空间可以达到4GB。单从寻址这方面说,使用16位寄存器的方法已经不够用了,必须要开发一种新方法。在保护模式下,虽然CPU还是使用原来16位的cs、ds寄存器表示内存地址的段值,不过保护模式下的段值只是一个索引,这个索引指向一个数据结构的一个表项就是GDT(or LDT)。
在保护模式下,CPU有着巨大的寻址能力,并为强大的32位操作系统提供了更好的硬件保障。
  www.2cto.com  
所以实模式和保护模式其实就是随着CPU性能不断增强后为了前后能够兼容而设计出来的一套模式。是一个历史遗留产物。
其实CPU的工作模式还有一种虚拟X86模式虚拟X86可以与保护模式相互转换且从虚拟模式只能通过复位信号到实模式。
--------------------------------------
为什么要分段?
分段的引入主要扩大了内存地址,程序的地址不再需要原始的硬编码,程序的调试也更简便。
当x86 CPU 工作在保护模式时,可以使用全部32根地址线访问4GB的内存,因为80386的所有通用寄存器都是32位的,所以用任何一个通用寄存器来间接寻址,不用分段就可以访问4G空间中任意的内存地址。但这并不意味着,此时段寄存器就不再有用了。实际上,段寄存器更加有用了,虽然再寻址上没有分段的限制了,但在保护模式下,一个地址空间是否可以被写入,可以被多少优先级的代码写入,是不是允许执行等等涉及保护的问题就出来了。要解决这些问题,必须对一个地址空间定义一些安全上的属性。
 
段寄存器这时就派上了用场。但是设计属性和保护模式下段的参数,要表示的信息太多了,要用64位长的数据才能表示。我们把着64位的属性数据叫做段描述符,上面说过,它包含3个变量:段物理首地址、段界限、段属性 80386的段寄存器是16位(注意:通用寄存器在保护模式下都是32位,但段寄存器没有被改变)的,无法放下保护模式下64位的段描述符。

如何解决这个问题呢?方法是把所有段的段描述符顺序存放在内存中的指定位置,组成一个段描述符表(Descriptor Table);而段寄存器中的16位用来做索引信息,这时,段寄存器中的信息不再是段地址了,而是段选择子(Selector)。可以通过它在段描述符表中“选择”一个项目已得到段的全部信息。那么段描述符表存放在哪里呢?80386引入了两个新的寄存器来管理段描述符,就是GDT和LDT。这样,用以下几步来总体体验下保护模式下寻址的机制
 
1、段寄存器中存放段选择子Selector 
2、GDT中存放着段描述符表的首地址 
3、通过选择子根据GDT中的首地址,就能找到对应的段描述符 
4、段描述符中有段的物理首地址,就得到段在内存中的首地址 
5、加上偏移量,就找到在这个段中存放的数据的线性地址(只有分段机制情况下,就是真实物理地址)。 
 
接上面所述,GDT的作用就是用来提供段式存储机制,这种机制是通过段寄存器和GDT中的描述符共同提供的。
因为要能够访问4GB内存,所以在32位模式下
物理地址不能等于 段值*16+偏移 (这种方法寻址1MB)
于是,设计者让
段值*16指向一个数据结构的一个表项就是GDT(or LDT),表项中详细定义了段的起始地址,界限和属性等内容 
于是原先“段:偏移”形式的逻辑地址经过段机制转化成线性地址
如果只有分段机制,那么这个地址就是对应的真实内存的物理地址。
--------------------------------------
为什么要分页?
其实它的主要目的在于实现虚拟存储器。
 
接上面所述,刚刚说到线性地址,并且说如果只有分段机制,线性地址就是物理地址
分段和分页是通过内存控制单元(MMU)进行的。分段使得逻辑地址转换为线性地址,而分页使得线性地址转换为物理地址。
   www.2cto.com  
在分页中,为了效率起见,将线性地址分成固定长度,称为页,与页长度一致的是页框(物理页)。每个页框包含一个页。
把线性地址映射到物理地址的数据结构称为页表。页表存放在主存之中,并在启用分页之前由内核对其进行初始化。
 
另外,如果你写完一个程序后,复制了一份,然后同时调试。你会发现,从变量地址到寄存器的值,这两个程序几乎全部是都是一样的,而这些一样的地址之间完全不会被混淆,而是各自完成自己的职责,这也是分页机制的功劳。
另外,因为分页机制的存在,程序使用的都是线性地址空间,而不再直接是物理地址。这好像是操作系统位应用程序提供了一个不依赖于硬件(物理内存)的平台,应用程序不必关心实际上有多少物理内存,也不必关心正在使用的是哪一段内存,甚至不必关心某一个地址是在物理内存里面还是在硬盘中。只要像操作系统申请就行,而操作系统全权负责了这其中的转换工作。

 原文:http://www.2cto.com/os/201210/161572.html
0 0
原创粉丝点击