Linux系统中的物理存储空间和虚拟存储空间的地址范围分别都是从0x00000000到0xFFFFFFFF,共4GB,但物理存储空间与虚拟存储空间布局完全不同。Linux运行在虚拟存储空间,并负责把系统中实际存在的远小于4GB的物理内存根据不同需求映射到整个4GB的虚拟存储空间中。Linux主要工作在保护模式下。80X86从逻辑地址到物理地址变换中经过了两个阶段。第一阶段使用分段机制把程序的逻辑地址变换成处理器可寻址内存空间(称为线性地址空间)中的地址。第二阶段的分页机制把线性地址转换成物理地址。第一阶段的分段变换机制是必须使用的,但是第二阶段的分页机制是可选择的。如果没有开启分页机制,那么分段机制产生的线性地址空间就直接映射到处理器的物理地址空间上。进行研究之前,一定要对概念定义非常清晰,不能混淆:

一、基本概念

1、物理地址: 放在寻址总线上的地址,用于内存芯片级内存单元寻址。放在寻址总线上,如果是读,电路根据这个地址每位的值就将相应地址的物理内存中的数据放到数据总线中传输。如果是写,电路根据这个地址每位的值就将相应地址的物理内存中放入数据总线上的内容。物理内存是以字节(8位)为单位编址的,是地址变换的最终结果地址,物理地址由32位或36位无符号整数表示。

2、逻辑地址:是指由程序产生的与段相关的偏移地址部分,每一个逻辑地址都由一个段和偏移量组成。在进行C语言指针编程中,可以读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址,不和绝对物理地址相干。只有在Intel实模式下,逻辑地址才和物理地址相等(因为实模式没有分段或分页机制,Cpu不进行自动地址转换);逻辑也就是在Intel 保护模式下程序执行代码段限长内的偏移地址(假定代码段、数据段如果完全一样)。

3、线性地址:是逻辑地址到物理地址变换之间的中间层。程序代码会产生逻辑地址,或者说是段中的偏移地址,加上相应段的基地址就生成了一个线性地址,是一个32位无符号整数,可以用来表示高达4GB的地址,也就是说,高达4294967296个内存单元,以十六进制表示,0x00000000到oxffffffff。如果启用了分页机制,那么线性地址可以再经变换以产生一个物理地址。若没有启用分页机制,那么线性地址直接就是物理地址。Intel 80386的线性地址空间容量为4G(2的32次方即32根地址总线寻址)。

4、虚拟内存:是指计算机呈现出要比实际拥有的内存大得多的内存量。因此它允许程序员编制并运行比实际系统拥有的内存大得多的程序。这使得许多大型项目也能够在具有有限内存资源的系统上实现。一个很恰当的比喻是:你不需要很长的轨道就可以让一列火车从上海开到北京。你只需要足够长的铁轨(比如说3公里)就可以完成这个任务。采取的方法是把后面的铁轨立刻铺到火车的前面,只要你的操作足够快并能满足要求,列车就能象在一条完整的轨道上运行。这也就是虚拟内存管理需要完成的任务。在现在操作系统中,都使用了MMU的存储管理技术,而MMU管理的地址是虚拟地址,虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如RAM)的使用也更有效率。有时我们也把逻辑地址称为虚拟地址。因为和虚拟内存空间的概念类似,逻辑地址也是和实际物理内存容量无关的。

二、逻辑地址如何转换为线性地址

   完整的内存管理,包含保护和地址变换两个关键部分。80386的工作模式包括实地址模式和虚地址模式(保护模式)。Linux主要工作在保护模式下。80X86从逻辑地址到物理地址变换中经过了两个阶段。第一阶段使用分段机制把程序的逻辑地址变换成处理器可寻址内存空间(称为线性地址空间)中的地址。第二阶段的分页机制把线性地址转换成物理地址。第一阶段的分段变换机制是必须使用的,但是第二阶段的分页机制是可选择的。如果没有开启分页机制,那么分段机制产生的线性地址空间就直接映射到处理器的物理地址空间上。

一个逻辑地址由两部份组成,段标识符: 段内偏移量。段标识符是由一个16位长的字段组成,称为段选择符。其中前13位是一个索引号。后面3位包含一些硬件细节,表示具体的是代码段寄存器还是栈段寄存器抑或是数据段寄存器,如图1所示。索引号就是“段描述符(segment descriptor)”的索引,段描述符具体地址描述了一个段。很多个段描述符,就组了一个数组,叫“段描述符表”,这样,可以通过段标识符的前13位,直接在段描述符表中找到一个具体的段描述符,这句话很关键,说明段标识符的具体作用,每一个段描述符由8个字节组成,如图2所示,与主题最密切的就是Base字段,她表示的是包含段的首字节的线性地址,也就是一个段的开始位置的线性地址。完全引用书中的一句话,一些全局的段描述符,就放在“全局段描述符表(GDT)”中,一些局部的,例如每个进程自己的,就放在所谓的“局部段描述符表(LDT)”中。那究竟什么时候该用GDT,什么时候该用LDT呢?这是由段选择符中的T1字段表示的,=0,表示用GDT,=1表示用LDT,GDT在内存中的地址和大小存放在CPU的gdtr控制寄存器中,而LDT则在ldtr寄存器中。这个过程中有几个基本的概念,一定要理清楚,如段选择符、段描述符、局部段描述符表、全局段描述符表。

图1 段选择符

图2 段描述符

图3详细显示了一个逻辑地址是怎样转换成相应线性地址的,给定一个完整的逻辑地址[段选择符:段内偏移地址],
       1、看段选择符的T1=0还是1,即先检查段选择符中的TI字段,以决定段描述符保存在哪一个描述符表中,知道当前要转换是GDT中的段(在这种情况下,分段单元从gdtr寄存器中得到GDT的线性基地址),还是LDT中的段(在这种情况下,分段单元从ldtr寄存器中得到GDT的线性基地址),再根据相应寄存器,得到其地址和大小。
       2、由于一个段描述符是8字节长,因此她在GDT或LDT内的相对地址是由段选择符的最高13位的值乘以8得到,拿出段选择符中前13位,可以在这个数组中,查找到对应的段描述符,这样,它了Offset,即偏移地址就知道了。
       3、把Base + offset,就是要转换的线性地址了。
       对于软件来讲,原则上就需要把硬件转换所需的信息准备好,就可以让硬件来完成这个转换了。图4 逻辑地址转换为线性地址实例,段选择符为0x7B,指向用户数据段,段起始地址为0x00000000,逻辑偏移地址为0x80495B0,最终的线性地址为Base + offset=0x80495B0。

图3 逻辑地址的转换

图4 逻辑地址转换为线性地址实例

参考文献:1、《深入Linux内核架构》;2、《深入理解Linux内核》;3、《Linux内核设计与实现》;4、《Linux内核设计的艺术》;

linux2.6 内存管理——逻辑地址转换为线性地址(逻辑地址、线性地址、物理地址、虚拟地址)的更多相关文章

  1. linux2.6 内存管理——概述

    在紧接着相当长的篇幅中,都是围绕着Linux如何管理内存进行阐述,在内核中分配内存并不是一件非常容易的事情,因为在此过程中必须遵从内核特定的状态约束.linux内存管理建立在基本的分页机制基础上,在l ...

  2. Linux内存管理--虚拟地址、逻辑地址、线性地址和物理地址的区别(二)【转】

    本文转载自:http://blog.csdn.net/yusiguyuan/article/details/9668363 这篇文章中介绍了四个名词的概念,下面针对四个地址的转换进行分析 CPU将一个 ...

  3. linux内存管理---物理地址、线性地址、虚拟地址、逻辑地址之间的转换

    linux内存管理---虚拟地址.逻辑地址.线性地址.物理地址的区别(一) 这篇文章中介绍了四个名词的概念,下面针对四个地址的转换进行分析 CPU将一个虚拟内存空间中的地址转换为物理地址,需要进行两步 ...

  4. Windows内存管理[转]

    本文主要内容:1.基本概念:物理内存.虚拟内存:物理地址.虚拟地址.逻辑地址:页目录,页表2.Windows内存管理3.CPU段式内存管理4.CPU页式内存管理 一.基本概念1. 两个内存概念物理内存 ...

  5. 关于linux内存管理

     Linux的内存管理主要分为两部分:物理地址到虚拟地址的映射,内核内存分配管理(主要基于slab). 物理地址到虚拟地址之间的映射 1.概念 物理地址(physical address) 用于内存芯 ...

  6. Linux内存管理和寻址详解

    1.概念 内存管理模式 段式:内存分为了多段,每段都是连续的内存,不同的段对应不用的用途.每个段的大小都不是统一的,会导致内存碎片和内存交换效率低的问题. 页式:内存划分为多个内存页进行管理,如在 L ...

  7. [转]linux内核分析笔记----内存管理

    转自:http://blog.csdn.net/Baiduluckyboy/article/details/9667933 内存管理,不用多说,言简意赅.在内核里分配内存还真不是件容易的事情,根本上是 ...

  8. 从内存管理原理,窥探OS内存管理机制

    摘要:本文将从最简单的内存管理原理说起,带大家一起窥探OS的内存管理机制,由此熟悉底层的内存管理机制,写出高效的应用程序. 本文分享自华为云社区<探索OS的内存管理原理>,作者:元闰子 . ...

  9. Linux内存管理 (6)vmalloc

    专题:Linux内存管理专题 关键词:vmalloc.页对齐.虚拟地址连续.物理不连续 至此,已经介绍了集中内核中内存分配函数,在开始简单做个对比总结Linux中常用内存分配函数的异同点,然后重点介绍 ...

随机推荐

  1. iOS代码规范(OC和Swift)

    下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...

  2. 【社工】NodeJS 应用仓库钓鱼

    前言 城堡总是从内部攻破的.再强大的系统,也得通过人来控制.如果将入侵直接从人这个环节发起,那么再坚固的防线,也都成为摆设. 下面分享一个例子,利用应用仓库,渗透到开发人员的系统中. 应用仓库 应用仓 ...

  3. 数据库优化案例——————某市中心医院HIS系统

    记得在自己学习数据库知识的时候特别喜欢看案例,因为优化的手段是容易掌握的,但是整体的优化思想是很难学会的.这也是为什么自己特别喜欢看案例,今天也开始分享自己做的优化案例. 最近一直很忙,博客产出也少的 ...

  4. 【开源】分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】

    由于个人研究需要,需要采集天气历史数据,前一篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子),介绍了基本的采集思路和核心代码,经过1个星期的采集,历史数据库 ...

  5. jQuery.Ajax IE8 无效(CORS)

    今天在开发的时候,遇到一个问题,$.get()在 IE8 浏览器不起作用,但 Chrome,Firefox 却是可以的,网上资料很多,最后发现是 IE8 默认不支持 CORS 请求,需要手动开启下: ...

  6. iOS之App Store上架被拒Legal - 5.1.5问题

    今天在看到App Store 上架过程中,苹果公司反馈的拒绝原因发现了这么一个问题: Legal - 5.1.5 Your app uses background location services ...

  7. 【转】 XenServer的架构

    一.Dom0或者控制域 XenServer从安装上看起来像是一个Linux,所以有些同学认为XenServer就是Linux或者是Linux修改的.真实的XenServer和Linux的关系是这样的: ...

  8. NoSql1 在Linux(CentOS)上安装memcached及使用

    前言:       今天是初五,生活基本要从过年的节奏中回归到正常的生活了,所以想想也该想想与工作有关的事情了.我之前在工作中会经常使用memcached和redis,但是自己一直没有时间系统的好好看 ...

  9. 简单的转盘抽奖——CSS动画优化

    前言 前两天去一家公司面试,被问到一些小游戏的东西.面试官提到了刷红包还有抽奖这些怎么实现,当时简单说了下思路,回来之后想想还是说的太轻描淡写了,干说不做就是耍流氓,所以就做了一个(Demo & ...

  10. Git入门资料汇总

    Git是一个非常好用的版本控制工具,同时,它也是一个相对比较复杂的工具,想要掌握它还是需要花一番功夫的.网络上关于Git的入门资料已经很多了,我就不再重复了,直接把我学习的文章放在这里. Git详解 ...