《深入理解linux内核》之内存寻址

逻辑地址:
逻辑地址由一个段和偏移量组成,偏移量指明了从段开始的地方到实际地址之间的距离。

线性地址(虚拟地址):
32位环境下,是一个32位无符号整数,可以用来表示高达4GB的地址。

物理地址:
用于内存芯片级内存单元寻址。它们与从微处理器的地址引脚发送到内存总线上的电信号相对应。

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

从80286开始,intel微处理器以实模式和保护模式执行地址转换。实模式存在的原因主要是兼容早期处理器,并让操作系统自举。

段选择符和段寄存器
Linux中,一个逻辑地址由两部分组成:一个段标识符(段选择符)和一个指定段内相对地址的偏移量。段寄存器用于存放段选择符。如cs、ss、ds、es、fs、gs。cs寄存器还有一个重要功能:它含有一个两位的字段,用于指明CPU的当前特权级(CPL)。0表示最高优先级,3表示最低。Linux只用0和3级,分别对应内核态和用户态。

段描述符
段描述符描述了段的特征。它放在全局描述表(GDT)或局部描述表(LDT)中。
通常只定义一个GDT,而每个进程除了存放在GDT中的段之外如还要需要创建附加段,就可以有自己的LDT。GDT在主存中的地址和大小放在gdtr控制寄存器,当前正在被使用的LDT地址和大小放在ldtr中。

快速访问段描述符
为了加速逻辑地址到线性地址的转换,80x86处理器提供一种附加的非编程寄存器,供6个可编程的段寄存器使用。每一个非编程的寄存器含有段描述符,由相应的段寄存器中的段选择符来指定。每当一个段选择符被装入寄存器时,相应的段描述符就由内存装入到对应的非编程CPU寄存器。从那时起,针对那个段的逻辑地址转换就可以不访问主存中的GDT或LDT,处理器只需直接饮用存放段描述符的CPU寄存器即可。仅当段寄存器的内容改变时,才有必要访问GDT或LDT。

Linux中的分段
Linux以非常有限的方式使用分段。2.6版的Linux只有在80x86结构下才需要使用分段。运行在用户态的所有Linux进程都使用一对相同的段来对指令和数据寻址。这两个段就是所谓的用户代码段和用户数据段。类似地,运行在内核态的所有Linux进程使用相同的内核代码段和内核数据段。事实上,这四个段的线性地址都从0开始,达到4G(32位环境下)寻址限长。由此得出一个结论,Linux下逻辑地址与线性地址是一致的,即逻辑地址的偏移量与线性地址一致。
CPU当前特权级(CPL)反映了进程是在用户态还是内核态,由存放在段寄存器的RPL字段决定。当特权级被改变,段寄存机必须相应的更新。

Linux GDT LDT
在但处理器系统中只有一个GDT,而在多处理器系统中每个CPU对应一个GDT。大多数用户态下的Linux程序不适用局部描述符表。

分页
分页单元把线性地址转换成物理地址。线性地址被分成以固定长度为单位的页。页内部连续的线性地址被映射到连续的物理地址中。分页单元把所有的RAM分成固定长度的页框(物理页)。每一个页框包含以个页,页框和页长度一致。把线性地址映射到物理地址的数据结构称为页表。页表存放在主存中,并在启用分页单元之前必须由内核对页表进行适当的初始化。80836开始所有80x86处理器都支持分页,通过设置cr0寄存器的PG标志启用。转换分两步完成,第一步基于页目录表,第二步基于页表。每个活动进程必须有一个分配给它的页目录,在进程需要一个页表时才给该页表分配RAM。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值