您的位置:首页 > 运维架构 > Linux

Linux-0.11内核源码分析系列:关于线性地址,逻辑地址,物理地址的关系与区别

2014-11-24 20:03 645 查看
/*
*Author  : DavidLin
*Date    : 2014-11-22pm
*Email   : linpeng1577@163.com or linpeng1577@gmail.com
*world   : the city of SZ, in China
*Ver     : 000.000.001
*history :     editor      time            do
*          1)LinPeng       2014-11-22      created this file!
*          2)
*/
    以下所有描述基于Linux0.11内核及其所编写的年代的所有物质和非物质基础
X86保护模式下编程规则:
    X86保护模式提供4G的物理地址空间,从0到0xFFFFFFFF。当然这只是地址总线上可以
寻址的空间大小,具体需要根据挂载在地址总线上的内存条大小确定。

物理地址:
    Linus在编写Linux0.11版本的时候,他的电脑只有16M内存,所以,Linux0.11源码中
描述的物理地址是从0-16M。

线性地址:
    线性地址也是从0到0xFFFFFFFF的平坦地址,如果没有开启分页机制,线性地址等于物
理地址。如果开启分页机制,线性地址到物理地址需要经过二级地址转换,不是顺序映射
关系。线性地址可以很大,但最终是运行在物理地址上面,而缺页机制和需求加载,就是为
了让远比物理内存大的程序,运行在如此小的物理内存中,如果物理内存足够大,或许这些
情况都不会发生。这个好比公交车上让座,假设座位是内存,其他站立空间是硬盘,刚上车
的时候你很高兴,你和你女朋友(进程A,B)都有座位,如果此时,有个孕妇上车了,售票
员大姐(操作系统)发现了,"孕妇优先",于是开始问"谁给孕妇让个座啊"(进程调度),
不过很不幸,这个系统是非抢占式的,孕妇(进程S)只好等待,作为一个有理想有道德的
程序猿,当仁不让,自己站了起来了(进程挂起),操作系统一看,有个家伙把座椅
(内存)释放出来了,于是排队等候的孕妇就坐到了你原来的位置,你切换到公交地板上
(硬盘)。车到某站,孕妇下车了,于是你重新坐上座位(内存占有),在公家车的整个运
营过程中,座位(内存)是有限的,而人不不断上下,所以人上来首先站在车厢内,然后根
据各种成文的,不成文的规矩,占有或者释放内存(座位)。座位是有限的,而人相对来说
是无限的,怎么利用有限的资源,服务更多的进程,这或许是操作系统应该考虑的。
为什么线性地址与物理地地址不是一一映射?这里举个例子,只是个人理解,不是很严谨:
比如在玩《英雄连》等游戏,运行文件达到了10G以上,远超过了XP 32位系统
所支持的4G内存空间,所以我们需要的不是程序一执行的时候就把所有的代码和数据加载到
内存中,而是需要的时候再进行加载,这就是所谓的需求加载。首先,登陆《英雄连》游戏
,游戏软件会向操作系统申请1块内存,假设这块内存大小是600M,假设刚好对应占有物理
地址0.6G-1.2G的物理地址空间,对于这个应用来说,它会认为自己占有了整个10G的内存,
在应用程序内部,它认为自己是从0地址(实际是物理地址600M处)开始的,游戏主控程序
会把自己的代码加载到它的0地址处,假设主控程序占用了相对地址的0-300M地址空间,
这部分程序长驻在内存中,只有游戏退出的时候才会被主动释放,而其他关卡选项,都是保
存在硬盘当中,只有需要的时候,才会加载到内存中(比如相对地址300-600M地址空间中)
。比如只玩关卡"虎式精英"的时候,内存只加载"虎式精英"这个关卡中的代码和地图数据,
而"诺曼底登陆"关卡的代码和数据都驻留在硬盘中,当玩家想由"虎式精英"关卡切换到"诺
曼底登陆"关卡时,"诺曼底登陆"关卡的代码和数据就覆盖了"虎式精英"关卡的代码和数据。
如果"诺曼底登陆关卡"地图数据都比600M空间还大怎么办?还是需求加载,这就是为什么当
年"传奇"游戏中,游戏人物行进会感觉地图缓慢的在电脑屏幕上铺开,因为是首先得把地图
从硬盘读到内存,显卡再显示内存中的数据,这是一个不断更新的过程。

逻辑地址:
    逻辑地址也叫做虚拟地址,指的是分段机制提供的地址,由段部分和一个偏移部分构
成。段机制是虚拟地址转换到线性地址的基础。线性地址 = 段基址 + 偏移地址。比如一个
数据段,给它分配了线性地址地址空间9M的位置,对于数据段内部来说,它其实是不知道哪
里是地址的开始地址的,所以它需要得到一个参考系。在程序的编译过程中,它都是认为数
据段开始的地方就是0地址,所以,通过段描述符获得段基址,加上(段内)偏移地址,得到
的就是线性地址。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐