Linux内存与地址空间管理.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Linux内存与地址空间管理

Linux内存与地址空间管理   本文以Linux 2.6版本内核为例,介绍了内核线性地址空间的布局,并描述了80386架构处理器下的3种内存地址的概念及在分段、分页机制下的相互转换。      通过内存地址访问,我们可以得到存在内存单元里的内容,这很容易理解。但在不同的环境下,会涉及到几种不同的内存地址的概念,初学者很容易混淆。为了方便后面的学习,我们以80X86架构处理器为例,把涉及的3种内存地址的概念分别做一解释。   逻辑地址(Logical Address):汇编程序中,我们经常会看到段基址加偏移量来表示内存地址的方式,如0100:20,1000:40,其实这就是逻辑地址。目前的MSDOS或Windows程序,利用了80X86架构处理器的分段机制,程序地址空间被分隔成若干个不同的段,如代码段,数据段等。自然地,内存地址就用段地址+段偏移来表示。和Windows不同,Linux只是有限地使用分段机制。Linux启动代码在实模式阶段,会显式地用逻辑地址;当进入保护模式后,内核和进程的代码数据段都被设置成相同的段基址0这时,段偏移量就等于线性地址,因而用线性地址表示内存地址更加方便。   线性地址(Linear Address):线性地址也被称作虚拟地址,在32位CPU架构下,可以表示4G的地址空间,用16进制表示就是00xffffffff。用线性地址寻址内存比逻辑地址更加直观,因此在Linux 中,无论内核地址空间还是进程地址空间,都是用线性地址来表示的。当然,访问内存最终还要利用物理地址的,所以线性地址在寻址时需要转换成物理地址。这种转换是由硬件自动完成的,我们会在后面的分页技术部份详细讨论。   物理地址 (Physical Address):物理地址顾名思义就是用来访问物理内存的地址表示方式。无论逻辑地址,还是线性地址,最终都要转换成物理地址来完成访存的过程。从电气层来讲,物理地址实际上是CPU地址引脚发往内存总线的电信号。   在80386处理器中,典型的逻辑地址,线性地址和物理地址的转换过程是这样的。内存管理单元(MMU)通过硬件分段机制把逻辑地址转换成线性地址,然后再通过硬件分页机制把线性地址转换为物理地址。这里,读者可能会感到有些困惑,一次访存操作要涉及到两次地址转换,效率会不会很低。其实,这种转换都是硬件自动完成的,无需软件参与,再加上TLB Cache等技术,实际访存效率还是比较高的。当然,转换的规则是需要软件提前初始化好的。      内存寻址   1.分段机制   分段机制是用分段的方法把程序的代码,数据以及堆栈分隔开来,从而保证在同一线性地址空间内,多个程序之间互不干扰的执行。   Intel从80286开始引入保护模式,因此逻辑地址到物理地址的转换方式和之前的实模式有了很大不同。实模式下的分段机制很简单,地址转换公式是:物理地址=段地址*16+段偏移,这里不赘述了。在保护模式下,逻辑地址是由段选择子和段偏移量两部分构成。其中,段选择子是16位长度,段偏移是32位长度。      图1 段选择子格式      段选择子标识一个段,通常被加载到段寄存器CS,DS,ES,SS,FS和GS来表示,如图1所示。INDEX表示所标识的段描述符在段描述符表(GDT or LDT)中的索引。TI表示所标识的段描述符是在全局还是本地段描述符表中。TI=0表示在全局描述符表(GDT)中,TI=1表示在本地描述符表(LDT)中。RPL表示请求特权级别,分0-3级,0级别最高。在Linux内核中,0代表内核态,3代表用户态。   80386的段描述符表分全局段描述符表(GDT)和局部描述符表(LDT)两类。其中,全局段描述符表最重要,它其实是一个存放在线性地址空间的结构数组,每个结构单元代表一个段描述符。逻辑地址通过其段选择子中的索引值,就可以定位到对应的段描述符上。   段描述符顾名思义,描述了线性地址空间的一个段。因为其格式比较复杂,这里就不一一罗列了,其中最重要的字段是段基地址(BASE)和大小(LIMIT),它们会参与到逻辑地址的转换过程。   事实上,分段机制和后面要讲到的分页机制都可以起到隔离不同进程的地址空间,因此功能上有些重复,再加上考虑和RISC架构的兼容性,因此,Linux只是很有限地使用了段机制。   在Linux中,4个最主要的段描述符-用户态代码和数据段,内核态代码和数据段都被设置成BASE=0x0000000, LIMIT=0xffffffff,因此,所有的用户进程包括内核都使用同样的线性地址空间,而且逻辑地址中的段偏移就等于线性地址。这样,除了用户态和内核态之间的切换外,在其它绝大多数情况下,段寄存器都不需要

文档评论(0)

189****7685 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档