zoukankan      html  css  js  c++  java
  • 页、页表和块


    CPU通过虚拟地址空间来间接访问内存的物理内存地址;

    虚拟地址空间,操作系统为进程分配的逻辑地址;
    操作系统负责将虚拟地址空间和物理内存地址之间建立映射关系

    虚拟地址空间的访问单位叫做页;一页大小一般在512Byte~8K之间;并且每个页都有编号;
    物理地址按照同样的大小为单位,叫做块;并且每个块都有编号;

    操作系统通过维护一张表,即页表;来维护虚拟页和物理块之间的映射关系;

    页表放在物理内存中,有操作系统负责维护;


    一个4G虚拟地址空间,将会产生1024*1024个页,页表的每一项存储一个页和一个块的映射,所以,至少需要1M个页表项。
    如果一个页表项大小为1Byte,则至少需要1M的空间,所以页表被放在物理内存中,由操作系统维护。
    每个进程都有一张页表,页表的起始地址和长度信息在进程不被CPU执行时,放在PCB中;

    先将具体的虚拟地址A/页面大小4K,结果的商作为页表号,结果的余作为业内地址偏移。
    CPU访问的虚拟地址:A
    页面:L
    页表号:(A/L)
    页内偏移:(A%L)

    虚拟地址结构
    31 - 12 //页表号
    11 - 0 //页内偏移

    CPU中有页表寄存器,存放当前进程的页表起始地址和页表长度;

    将上述计算的页表号和页表长度进行对比,确认在页表范围内,
    然后将页表号和页表项长度相乘,得到目标页相对于页表基地址的偏移量。
    最后加上页表基地址偏移量就可以访问到相对应的块了。
    CPU拿到框的起始地址之后,再把页内偏移地址加上,访问到最终的目标地址。

    按照上述的过程,可以发现,CPU对内存的一次访问动作需要访问两次物理内存才能达到目的,
    第一次,拿到框的起始地址,第二次,访问最终物理地址。

    为了提高CPU对内存的访问效率,在CPU第一次访问内存之前,
    加了一个快速缓冲区寄存器,它里面存放了近期访问过的页表项。

     

    页表分级:
    分级的本质其实也是将页表项进行分组管理;
    考虑到进程内存大部分空闲以及局部性,因此实际记录的时候大部分的记录是没有的;
    也就不需要拿出一大段连续的空间来作为页表记录映射关系;
    页表项存储的是物理内存一页的物理地址,因此一个页表项只能指向一页;或者叫一块;

    两级分页机制将32位的虚拟空间分成三段;
    低十二位表示页内偏移,高20分成两段分别表示两级页表的偏移。
    * PGD(Page Global Directory): 最高10位,全局页目录表索引
    * PTE(Page Table Entry):中间10位,页表入口索引
    在进行地址转换时,结合CR3寄存器中存放的全局页表物理地址,然后加上虚拟地址的高10位也就是PGD段,作为页表偏移找到相应的页表项,从改页表项得到二级页表的物理地址,然后结合中间十位即PTE段,作为偏移找到PTE项,即获得了要访问的内存地址所在的物理页,然后结合Page Offset即定位到了需要访问的物理内存,这样就完成了从虚拟地址到物理地址的转换。
    如果没有缓存的情况下,整个过程需要三次内存访问。
    //分级页表节约了空间,当然增加了访问内存的次数;牺牲了时间;


    Linux的三级页表:
    Intel通过在处理器上把管脚数从32增加到36,以提高处理器的寻址能力,使其达到236=64GB,
    但是linux依然使用32位的虚拟寻址空间,为此,需引入一种新的分页机制。
    如果页的大小依然是4k, 64G的内存可以分为224个页框;

    如果页的大小依然是4k,64G(234)的内存可以分为2的24次方个页框,
    然后页表项的物理地址字段从20位扩展到24位,每个页表项必须包含12个标志位(固定)和24个物理地址位(36-12),共36位,因此,每个页表项须从32位扩展到64位(36位>32位,考虑到对齐,因此应将页表项扩大一倍到64位)。
    所以原来32位的页表项现在变成了64位后,一页可以存储的页表项从1024变成了512,需要9位进行寻址,高一级的页表也需要9位,加上页内偏移12位,现在32位的地址还剩余2位,因此又引入一级页表,该页表只含有4个页表项。这样就解决了PAE情况下的分页。

    虽然页表项扩展到了64位,选址达到了36位,即64G的空间,但是实际上一个进程可以使用的虚拟空间大小仍然是4G,
    因为虚拟地址依然只有32位,即使每个页表项都填满也只能有4G的空间。
    唯一不同的是物理内存进行分配时候就可以使用超过4G的空间了。

    Linux的四级页表:
    随着硬件的发展,64位的CPU出现了,这个时候基于32位处理器的三级页表又不能使用了,不过现在的硬件已经可以支持四级页表了,
    可以使用48位的虚拟空间了(虚拟空间的位数和硬件的对应关系理的还不是很清楚),经过前辈们的争论,最后确定了下面的四级页表形式:



    参考文档:

    linux-----页、页表、页框(块):https://blog.csdn.net/u014338577/article/details/82750771
    操作系统页表管理:https://blog.csdn.net/kongdefei5000/article/details/70183178

    知行合一
  • 相关阅读:
    C++中几种字符串表示方法
    oracle11g卸载(win10)
    Dbvisualizer 连接oracle数据库
    严重: Exception starting filter struts2 Unable to load configuration.
    eclipse启动Tomcat服务输入http://localhost:8080/报404
    Tomcat内存溢出解决办法
    A Java Runtime Environment(JRE) or Java Development Kit (JDK) must be available in order to run Eclipse.
    Spring容器装配bean的方式
    Spring容器的基本实现
    spring环境搭建
  • 原文地址:https://www.cnblogs.com/grooovvve/p/14646141.html
Copyright © 2011-2022 走看看