操作系统的分页机制
分段却能大大提高编程者管理程序的效率。故而32位机也采用了段+偏移的模式来寻址。但与实模型不同的是,由于地址线和数据线宽度一致,因而,每个段最大可以到4G,并且段基址也是32位的无需进行左移处理。在地址储存模型中这属于“段地址储存模型”。然而需要注意的是,在32位机里,虽然通用寄存器,标志寄存器等都扩展成了32位,但是段寄存器却依然是16位的(为什么不做改变??我猜可能是这样便于向下兼容)。所以在32位寻址时,段寄存器里放的不再是段基址(位数不够,放不下)而是一个选择子.
分页
1) 如果没有分页机制,则由分段寻址方式计算出的地址即为物理地址。
2) 分页机制为程序提供了4G的连续地址空间。
3) 每个页占据4k,则4G的地址空间需要4G/4K = 1M个页。每个页需要4个字节来描述其物理基地址。这样则需要4M的地址空间存放页信息。
4) 操作系统将每1024个页分成一组,组成一个页表,页表项中保存该页的物理基地址。则最多有1024个页表。
5) 目录表中有1024个项,每个项占用4个字节,项的内容为页表的地址。
寻址过程
CR3寄存器(CR3高20位)
|
页目录地址
|
索引到页表
|
索引到页
|
得到页表的地址和有关信息
|
页表中的基址与线性地址中的offset位段(后12位)相加得到物理地址
页目录地址:
在32位cpu里,CR3寄存器里高20位放的就是页目录的地址,因为页目录的低12位总是0,这样保证页目录始终是页对齐的(每页大小4kB)。页目录大小为4mb 分成了1024个页表,页表包含1024个页表项
虚拟地址/线性地址:
它是逻辑地址到物理地址的中间层,也叫线性地址,是基于段寄存器对逻辑地址转换得到的。虚拟地址通过页转(一般由硬件的MMU完成)换得到真实的物理地址。
X86体系有一个只有系统软件才能操作的寄存器cr3,存了最高一级页表的物理地址,cpu拿到一个虚拟地址后会自动从cr3中拿到页表,然后用页表转换,得到最终的物理地址。
每个进程都可以有独立的逻辑地址,进程切换时,OS会把cr3换成这个进程相应的页表(每个进程都有独立的页表数据)。
需要强调的是进程映射空间为0G~3G,操作系统把自己映射到了3G~4G的空间,并且映射到了每一个进程空间,也就是说,每一个进程的3G~4G空间的映射都是一样的(每个进程维护一个页表),都为操作系统物理地址的映射。这样,进程切换时,虽然页表换了,但处于内核态的操作系统的从虚拟地址到物理地址的映射是不会改变的,保证了此时操作系统能顺利进行下去。
CR3寄存器:
1、分页单元中,页目录是唯一的,它的地址放在CPU的cr3寄存器中,是进行地址转换的开始点。万里长征就从此长始了。
2、每一个活动的进程,因为都有其独立的对应的虚似内存(页目录也是唯一的),那么它也对应了一个独立的页目录地址。——运行一个进程,需要将它的页目录地址放到cr3寄存器中,将别个的保存下来。
3、每一个32位的线性地址被划分为三部份,面目录索引(10位):页表索引(10位):偏移(12位)
依据以下步骤进行转换:
1、从cr3中取出进程的页目录地址(操作系统负责在调度进程的时候,把这个地址装入对应寄存器);
2、根据线性地址前十位,在数组中,找到对应的索引项,因为引入了二级管理模式,页目录中的项,不再是页的地址,而是一个页表的地址。(又引入了一个数组),页的地址被放到页表中去了。
3、根据线性地址的中间十位,在页表(也是数组)中找到页的起始地址;
4、将页的起始地址与线性地址中最后12位相加,得到最终我们想要的葫芦;
分页和分段的区别:
1)页是信息的物理单位;段是信息的逻辑单位。
2)页的大小固定且由系统确定;段的长度不固定(取决于用户所编写的程序,通常由编译程序在对源程序编译时,根据信息的性质来划分)。
3)分页的作业地址空间是一维的,只需一个记忆符,就可表示一个地址;分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。
4)分段物理空间不连续,但段内是连续的;分页物理空间不连续。
实际物理地址的计算
1.从CR3寄存器高20位里取出页目录的基地址.
2.目录的基地址+偏移地址(线性地址高10位)从目录中取出页表基地址
3.页表基地址+偏移地址(线性地址中间10位)从也表中取出页基地址
4.将页面描述项中给出的页面基地址与线性地址中的offset位段(后12位)相加得到物理地址
那是因为4KB为一簇。我猜的。因为我不认为这跟32位系统有关系,只跟你的分区格式有关系。
你看的是内存小页吗, 小页就这么大啊