免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234567
最近访问板块 发新帖
楼主: chenzhanyiczy
打印 上一主题 下一主题

虚拟地址问题求助!!高手进!! [复制链接]

论坛徽章:
0
61 [报告]
发表于 2009-11-15 13:50 |只看该作者
原帖由 billypeng 于 2009-11-14 16:49 发表


不是Linux巧妙绕过分段模式,而是Intel有意提供这样的方便。当初Intel为解决16位寄存器下更大的访问地址空间,花了很大的精力。

8086采用段寄存器和偏移寄存器,解决了20位地址,1MB空间。

很快1MB不 ...



Intel 从8086一路走过来, 为了兼容花了很大精力,也做得很辛苦,这也是为什么总有人在抱怨说x86架构相对比较复杂的原因之一。

Intel 全系列的x86 CPU都是向后兼容的, 都兼容最早的8086的实模式,哪怕是启用PAE扩展物理机制(可访问64G物理内存)的Pentium Pro也是兼容早期的实模式的。

至于是Intel有意提供这样的方便, 还是Linux在设计时有意避过了分段的模式。这个并不是最重要的,而且这里面的最深层的原因恐怕只有原始设计者才真正清楚。
比如说, x86的权限(DPL)分级模式共有4级, 从0~3,但是Linux只使用0和3最高和最低的两级,来区分内核态(CPL=0)和用户态(CPL=3),其余的两级并没有使用。

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
62 [报告]
发表于 2009-11-17 19:08 |只看该作者
一切的一切都是来自赵炯 Linux 内核完全剖析 的这段描述:段限长定义了在虚拟地址空间中段的大小。段基址和段限长定义了段所映射的线性地址范围或区域。段内0到limit的地址范围对应线性地址中范围Base到Base+Limit。偏移量大于段限长的虚拟地址是无意义的,如果使用则会导致异常。另外,若访问一个段并没有得到段属性许可则也会导致异常。例如,如果你试图写一个只读的段,那么80386就会产生一个异常。另外,多个段映射到线性地址中的范围可以部分重叠或覆盖,甚至完全重叠,如图4-6所示。在本书介绍的Linux 0.1x系统中,一个任务的代码段和数据段的段限长相同,并被映射到线性地址完全相同而重叠的区域上。

对于粗体的文字,我现在有个自己的解析,但不知道正不正确?

代码段和数据段所映射的线性地址可以完全重叠,因为两者的段的基地址相同,再加上段限长也相同,所以可以完全重叠。
虽然是完全重叠,但一个线性地址只能映射回一个虚拟地址,这个虚拟地址要么是属于代码段的,要么是属于数据段的。
但就上我之前问的那样--“每个段(如数据段,代码段)的范围都是0-4G,既然段的基地址相同,段限长也相同,那么线性地址就有可能重复,因为偏移量有可能相同”,原来根本不会出现偏移量相同的现象,为什么呢?因为虽然每个段的范围都是0-4G,可这个范围是相对的,也就是说比如:代码段的范围是0-4G,接着是数据段,那么它的范围是4G-8G,这是相对于数据段来说是0-4G,所以偏移量是不可能相同的

论坛徽章:
0
63 [报告]
发表于 2009-11-18 00:00 |只看该作者
提醒下LZ. 如果你一定要把 分段机制搞清楚. 最好先选定一个目标. 赵博士那本书讲的时LINUX 0.11. 它和后期的LINUX 2.4, 2.6 内核差别很大. 就好像WIN 3.1 和 VISTA一样.

你上面讲的那些基本上对, 但是"每个段(如数据段,代码段)的范围都是0-4G" 这句不对. 如果是 0.11. 它利用了分段机制,那么每个段不会有4G那么大.
如果是后期的2.4, 2.6, 他们没有用分段机制, 所以每个段都是从0到4G. 然后通过分页机制来提供进程保护.

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
64 [报告]
发表于 2009-11-18 00:13 |只看该作者
原帖由 accessory 于 2009-11-18 00:00 发表
提醒下LZ. 如果你一定要把 分段机制搞清楚. 最好先选定一个目标. 赵博士那本书讲的时LINUX 0.11. 它和后期的LINUX 2.4, 2.6 内核差别很大. 就好像WIN 3.1 和 VISTA一样.

你上面讲的那些基本上对, 但是"每个 ...


假设在linux 0.11上面,每个段都用到了0-4G,那么我说到的:

"原来根本不会出现偏移量相同的现象,为什么呢?因为虽然每个段的范围都是0-4G,可这个范围是相对的,也就是说比如:代码段的范围是0-4G,接着是数据段,那么它的范围是4G-8G,这是相对于数据段来说是0-4G,所以偏移量是不可能相同的 "

这句话对吗? 谢谢!

论坛徽章:
0
65 [报告]
发表于 2009-11-18 00:48 |只看该作者
还有一个地方需要明确的定义. 你所针对的CPU 到底是什么类型的. 比如INTEL 32 BIT, 64 BIT? 有没有PAE?

假设最简单的情况, INTEL 32 BIT CPU, NO PAE. 那么即使你使用了分段,每个都弄成4G大小.他们最后都只能映射到 相同的 4G的 线性地址空间. 具体看这个帖子里的 11 楼.
http://linux.chinaunix.net/bbs/thread-1137218-2-2.html

在这种情况下,根本就没有 4G-8G这么一段线性地址可以给你用. 因为CPU 硬件就不支持.

假设CPU 开启了PAE功能,那么它最大支持64G的线性地址空间. 在这种情况下,你"也许"可以把PROCESS 0的代码段映射到0-4G. 数据段映射到4-8G. 那么一个PROCESS 就占用了 8G. 也就是说你的系统最多能同时跑的PROCESS = 64/8=8 个.  如果你自己设计OS, 不在乎这些,那么也许可以这样实现. 但是对于LINUX来说, 同时支持的PROCESS 肯定要远远大于8, 所以它不会这么用分段机制.

建议你好好读读INTEL CPU 手册. 先把硬件搞清楚.

论坛徽章:
0
66 [报告]
发表于 2009-11-18 03:47 |只看该作者
另外,我怀疑LZ你把文件格式里的"段"和CPU提供的"段"搞混了.
常见的文件格式,比如PE, ELF 都支持不同的"段", 英文是SECTION, 比如CODE SECTION, DATA SECTION. 这些和CPU提供的"段" SEGMENT 是不一样的. 完全没有关系. 比如说, 可以一个SECTION 对应一个 SEGMENT. 可以许多SECTION 对应一个SEGMENT. 还可以一个SECTION 对应很多SEGMENT. 也就是1对1. 1对多. 多对1.

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
67 [报告]
发表于 2009-11-18 09:35 |只看该作者
用文字有时真不好说明问题,

代码段和数据段所映射的线性地址可以完全重叠,因为两者的段的基地址相同,再加上段限长也相同,所以可以完全重叠。
虽然是完全重叠,但一个线性地址只能映射回一个虚拟地址,这个虚拟地址要么是属于代码段的,要么是属于数据段的。
但就上我之前问的那样--“每个段(如数据段,代码段)的范围都是0-4G,既然段的基地址相同,段限长也相同,那么线性地址就有可能重复,因为偏移量有可能相同”,原来根本不会出现偏移量相同的现象,为什么呢?因为虽然每个段的范围都是0-4G,可这个范围是相对的,也就是说比如:代码段的范围是0-4G,接着是数据段,那么它的范围是4G-8G,这是相对于数据段来说是0-4G,所以偏移量是不可能相同的

上面先回顾一下偏移量,基地址等。

其实上面那段话,我的原意是:

每个段的虚拟地址空间都是0-4G, 假设有16K的段,那么整个程序的虚拟地址空间总范围是64TB,那么代码段内的某地址它的偏移量是相对于代码段的虚拟地址空间0-4G,还是相对于整个虚拟地址空间64TB的?

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
68 [报告]
发表于 2009-11-18 13:16 |只看该作者
accessory 大侠呢?

论坛徽章:
0
69 [报告]
发表于 2009-11-18 13:35 |只看该作者
LZ, 建议你把65,66楼的帖子再仔细读读. 根本就没有64TB 地址这么一说。
另外,偏移量当然是相对于基地址的。也就是段的基地址。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP