《深入理解Linux内核》笔记--内存寻址

来源:互联网 发布:php 随机数原理 编辑:程序博客网 时间:2024/05/16 14:50

        在80x86微处理器中,存在三种地址,即逻辑地址,线性地址和物理地址。

        逻辑地址由段和偏移量组成。线性地址是一个32位无符号整数,可以用来表示高达4GB的地址。物理地址用于内存芯片级内存单元寻址。他们与从微处理器的地址引脚发送到内存总线上的电信号相对应。物理地址由32位或36位无符号整数表示。

        内存控制单元(MMU)通过一种称为分段单元的硬件电路把一个逻辑地址转换成线性地址;接着,分页单元的硬件电路把线性地址转换成一个物理地址。

        从80286模型开始,Intel微处理器以实模式和保护模式两种不同的方式执行地址转换。实模式存在的主要原因是要维持处理器与早期模型兼容,保护模式是为了对内存进行保护,防止进程访问无权访问的内存单元。

        一个逻辑地址由段标识符和一个指定段内相对地址的偏移量组成。段标识符是一个16位长的字段,称为段选择符,段选择符包含一个13位的索引号,1位的Ti用来指明是全局描述符表还是局部描述符表以及两位的RPL指明请求者权限,0表示内核态,3表示用户态;偏移量是一个32位长的字段。为了快速方便的找到段选择符,处理器提供6个段寄存器,分别为cs,ss,ds,es,fs和gs,其中cs为代码段寄存器,ss为栈段寄存器,ds为数据段寄存器。cs中包含一个两位字段,用来指明cpu当前特权,Linux用0表示内核态,3表示用户态。

        Linux中每个段由一个8字节的段描述符表示,存放在全局描述符表或者局部描述符表中。段描述符中包含32位段的首字节的线性地址(Base)和其他一些用以描述类型,权限,段长度之类的标志位。

        把一个逻辑地址转换成线性地址,先检查段选择符的Ti字段,确定段选择符是在全局描述符表中还是局部描述符表中。然后通过段选择符的13位字长的索引号在对应描述符表中的段描述符。最后,把逻辑地址的偏移量与段描述符Base字段的值相加得到线性地址。

        分段可以给每一个进程分配不同的线性地址空间,而分页可以把同一线性地址空间映射到不同的物理空间。与分段相比,Linux更喜欢使用分页方式,因为:当所有进程使用相同的段寄存器值时,内存管理变得更简单,也就是说他们能共享同样的一组线性地址;Linux设计目标之一是可以把他移植到绝大多数流行的处理器平台,而RISC体系结构对分段的支持很有限。

        在但处理器系统中只有一个全局描述符表,多处理器中,每个cpu对应一个全局描述符表,全局描述符表包含18个段描述符和14个空的,未使用的或者保留的。大多数的用户态下的Linux程序不使用局部描述符表,内核定义了一个缺省的局部描述符表供大多数进程共享。

        分页单元把线性地址转换成物理地址。其中一个关键任务是把所有请求与访问类型的线性地址的访问权限比较,组织无权访问。分页也使得操作系统更充分的使用内存,减少内存碎片。为了效率起见,线性地址被分成固定长度的组,称为页。页内部连续的线性地址被映射到连续的物理地址中。这样,内核可以指定一个页的物理地址和其存取权限,而不用指定页所包含的全部线性地址的存取权限。习惯上,我们使用术语“页”即指一组线性地址,又指包含在这组地址中的数据。

        从80386起,Intel处理器的分页单元处理4KB的页。32位线性地址被分成三个域:10位Directory,10位的Table和12位的Offset。线性地址的转换分成两步完成,每一步都基于一种转换表,第一种转换表称为页目录表,第二种转换表为页表。使用这种二级模式的目的在于减少每个进程页所需RAM数量。

        从Pentium模型开始,80x86微处理器引入了扩展分页,它允许页框大小为4MB而不是4KB,扩展分页用于把大段连续的线性地址转换成相应的物理地址。当页框大小为4MB时,故每一个物理地址都是在以4MB为边界的地方开始的。所以其物理地址的最低22位都为0,所以可以用10位来表示其地址。通过设置页目录项的Page Size标志启用扩展分页功能的情况下,分页单元把32位线性地址分成两个字段:10位Directory和22位Offset。

        页的存取权限只有两种,如果页目录项火页表项的Read/Write标志等于0,说明相应的页表或页是只读的,否则是可读写的。

        Intel通过在他的处理器上把管脚数从32增加到36来满足现代计算机对大于4GB的RAM的需求。从Pentium Pro处理器开始,Intel引入一种叫做物理地址扩展(PAE)的机制。通过设置cr4控制寄存器中的物理地址扩展标志激活PAE。页目录项中的页大小标志PS启用大尺寸页。

        64GB的RAM被分成2^24个页框,页表项的物理地址字段从20位扩展到24位。因为页表必须包含12个标志位和24个地址位,所以页表项从32位变为64位,结果一个4KB的页表包含512个表项,而不是1024个表项。通过页目录项中的PS标志,可以把32位线性地址分成两种方式来解释。

        Linux对于所有的页框都启用高速缓存,对于写操作总是采用回写。

       


0 0