x64存储管理机制初窥
前几天,上这问x64存储管理机制,经prolj和mik指点,去找intel手册和AMD手册看,看完之后把我的理解写下,
如有什么理解偏差之处,还望各位不要笑话,毕竟本人英语也是cai啊,:lol:
1.长模式(long mode)
在AMD64架构的长模式中包括两个子模式:64bit模式和compatibility模式。
● 64bit模式:在此模式中虚拟地址空间使用平坦(flat)模式,段寄存器包括CS,DS,ES,SS全部清零(FS,GS除外,在线性地址计算时,提供额外
的base寄存器寻址某些OS的系统数据结构),
能为64bit的OS和应用程序提供64位寻址支持。
●compatiblity模式:在此模式中使用与lagecy保护模式一样的存储管理模式,为的是平滑运行32bit
和16bit的应用程序,无需重新编译
注意:在长模式中不支持实模式和虚拟8086模式!!
图
由于在64bit模式下使用flat模式,所以无lagecy保护模式下的分段管理模式,所以虚拟地址直接对应线性地址。所以x64的分页
管理模式才是64bit下的重头戏
2.x64分页管理模式
如下图,是x86-64下的所有页大小和物理地址大小的汇总
图
在x64下,理论上可以通过使用PAE(物理地址扩展)分页结构支持64bit的线性地址到52bit物理地址的映射的,但在对这一架构的首次实现中,
只实现了48位的线性地址到40位物理地址的映射。现在你可以通过CPUID指令查看自己的cpu所支持的最大物理地址(MAXPHYDDR).
大家一定还记得在lagecy保护模式下通过PAE功能来访问超过32bit(36bit)的物理地址,但是在x64模式下的PAE与先前的PAE是不一样的!!
从线性地址到物理地址的转换中用到了四级页数据结构,一个新的页表数据结构---PML4被引入用来指向页目录指针表。PML4表
只能在x64模式下使用。而且页目录表指针从原来的4个项增加到了512个,所以要从线性地址中分配9bit用来索引PDP表(原来是2bit)。
PDE和PTE的大小保持不变。所以我们可以看到PML4+PDP+PDE+PTE+page offset=48bit,高16bit保留(其实是用以符号扩展,下面将看到
符号扩展的用途)。
CR3指向了PML4的基地址。
需要注意的是在使用x64模式之前,必须使CR4.PAE=1(PAE用来扩展PDE和PTE至64bit)。如果你在未使CR4.PAE=1之前,企图开启
x64模式的话,会引发#GP异常。
我们从上图还可以看到页大小的选择完全取决于PDE.PS(但我并没有在文档中看到ps位,是直接在文档中置1或0),无视CR4.PSE的存在。
2.1x64分页管理(4kb)
上图再说
图
●sign extended--符号扩展位
●PML4 entry--在线性地址39~47bit用于索引PML4 entry,指向PDP
●PDP entry--在线性地址的30~38bit用来索引PDP entry,指向PDE
●PDE entry--在线性地址的21~29bit用来索引PDEentry,指向PTE
●PTE entry--在线性地址的12~20bit用来索引PTE entry,指向page offset
●page offset--在线性地址的0~11bit提供在页中的offset
2.2x64分页管理(2mb)
图
我们可以看到与4kb的页相比少了PTE,page offset从原来的12bit增加到了21bit
下面我们来看看各页表项的内部结构
图(4kb)
上图看到,用上述方法可以得到512×512×512×512=2^36个页面,2^36*4kb=2^48个线性地址
图(2MB)
上图看到,用上述方法可以得到512×512×512=2^27个页面,2^27*2mb=2^48个线性地址
0bit:P位,即存在位,表示由项所指的页面或页表当前是否加载到了物理存储器中,如不存在,可以通过引发#PF异常从磁盘中
加载到物理存储器中
1bit:R/W,即读写位,为页表指定读写特权,当置位时可读可写;清零是只读
2bit:用户/系统位,即为页表指定系统还是普通用户特权
3bit:页面通写,指定高速缓存写策略是回写还是通写
4bit:高速缓存禁止位,当置位时禁止相关的页面和页表进行高速缓存,反之,可以
5bit:访问位,当置位时表示已经被访问,反之,没有
6bit(非PTE或PDE(2MB)):可用位
6bit(PTE或PDE(2MB)):D位,dirty,即脏位,置位时表示页面被写过
7~8bit(非PTE或PDE(2MB)):0
avail:系统程序员可用
G:全局标志
PAT:页表属性
各种base address是用来得到下一级表的基地址的,
最后的物理地址=page base address*2^12(2^21)+2^12(2^21),而page base address的大小取决于你的cpu的最大物理地址了。
3.最后,我来看一看sign extended会形成什么效果。
由于sign extended的作用会将线性地址分成相同大小的两段,从0至00007FFF`FFFFFFFF,
以及从 FFFF8000`00000000至FFFFFFFF`FFFFFFFF总计256TB的地址范围,这非常符合操作系统的习惯。
这种“古怪”的规则为日后扩展到真正的64位寻址保留了一个重要的特性:很多的操作系统(包括但不限于Windows NT系列)
将地址空间的高半部分(被称作内核空间)留给自己,将低半部分(用户空间)留给应用程序代码、用户态栈、堆和其他数
据区。这种设计保证了每一个符合AMD64的实现都拥有两个内存片段:低半段从00000000`00000000开始,
随着更多的虚拟地址位变得可用而“向上生长”;高半部分被“悬挂”在地址空间的顶部而“向下生长”。同样,
将未被使用的地址位内容固定下来防止被操作系统用作标志位、特权级标号等其他用途,是为了避免当架构扩展至52,
56, 60 和64位的时候出现问题。
图
参考资料:
1.http://zh.wikipedia.org/zh-cn/X86-64
2.intel手册
3AMD手册
[ 本帖最后由 child_z 于 2009-12-3 22:12 编辑 ] 原帖由 谢哥哥 于 2009-12-3 15:17 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
我们都是好孩子啊!
:shock: 怎么快?本来想自己顶的,被你抢先了 彩图用什么画的?挺鲜艳的。看字题是XP下面的。我只会用pgf/tikz,据说这个Asymptote可以达到专业效果,也很易学,类C语法。
mik对x64那可不是一般的熟悉啊,这是不用说的秘密。
===============================================
x64的处理器,加电的时候还是real mode的,然后跳转成compatiblity/IA32 mode,最后再跳到long mode
lz可以对这方面了解一下,写点儿东西,网上前两年这方面的东西还少。
回复 #5 prolj 的帖子
1.彩图并非本人所画,来源于http://zh.wikipedia.org/zh-cn/X86-64 :lol:2.mik简直把pc平台下的底层原理翻了个遍,好像还有涉及powerpc架构的,厉害~
3.网上关于x64的一些实现原理确实很少(应该说是在国内很少),我其实被逼看手册的。:lol:
4.您说的pgf/tikz我没用过,嘻嘻,不过好像是很强大的绘图工具,学习一下,将来好办事 你的字搞得太小了吧
回复 #7 mik 的帖子
好像是小了点啊,呵呵 上面的彩图中,所描述的 noncanonical address 是不对的。地址中只要符合,高 16 是 0 或 1 ,它就属于 canonical address
回复 #9 mik 的帖子
:em14: 符号扩展不是通过第47位来的嘛?比如0000FFFF_FFFFFFFF肯定是不行的啊[ 本帖最后由 child_z 于 2009-12-3 22:23 编辑 ]
页:
[1]
2