zoukankan      html  css  js  c++  java
  • MIT-JOS系列:用户态访问页表项详解

    在MIT-JOS lab4的实验中,为了能够在用户态自定义处理页面错误,我们必须要知道操作的页面的属性(是否当前用户具有读写权限、是否copy on write页面),这就需要查询指向当前物理页面的页表项和目录表项获取它的属性

    在之前的实验中,我们已经通过e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) | PTE_P | PTE_U;修改UVPT的目录表项,用此操作允许用户读取任一页面的页表项,但没有对其进行详细解释,因此在lab4的应用中遇到了一些障碍:不知道具体是怎么用UVPT定位到一个页面对应的页表项。在这里,将对这个进行详细解释

    定义梳理

    解释原理前,首先列出各变量和宏的定义,以帮助说明和理解:

    • uvptpte_t uvpt[] = UVPT;
    • uvpdpde_t uvpd[] = UVPT+(UVPT>>12)*4;

    对线性地址la的分解如下:

    // A linear address 'la' has a three-part structure as follows:
    //
    // +--------10------+-------10-------+---------12----------+
    // | Page Directory |   Page Table   | Offset within Page  |
    // |      Index     |      Index     |                     |
    // +----------------+----------------+---------------------+
    //  --- PDX(la) --/ --- PTX(la) --/ ---- PGOFF(la) ----/
    //  ---------- PGNUM(la) ----------/
    

    PGNUM(la)获取的是虚拟地址la是第几个虚拟页面

    UVPT处的内存布局如下:

    /*                     :              .               :                   
     *                     :              .               :                   
     *    MMIOLIM ------>  +------------------------------+ 0xefc00000
     *                     |       Memory-mapped I/O      | RW/--  PTSIZE
     * ULIM, MMIOBASE -->  +------------------------------+ 0xef800000
     *                     |  Cur. Page Table (User R-)   | R-/R-  PTSIZE
     *    UVPT      ---->  +------------------------------+ 0xef400000
     *                     |          RO PAGES            | R-/R-  PTSIZE
     *    UPAGES    ---->  +------------------------------+ 0xef000000
     *                     |           RO ENVS            | R-/R-  PTSIZE
     * UTOP,UENVS ------>  +------------------------------+ 0xeec00000
     *                     :              .               :                   
     *                     :              .               :                   
     */
    

    UVPT占总共PTSIZE的物理内存,每一个页表项4个字节,总共有1024×1024个页表项,这一段足够索引到所有页表项。该段地址以只读权限开放给用户态的程序

    虚拟地址与页表的对应关系

    首先要明确一点,虽然一个虚拟页面映射到哪个物理页面是随系统分配的,但虚拟页面在页表中的结构总是固定的,例如第0个虚拟页面地址总是0-FFF,它总是对应页表目录的第0项和第0个二级页表的第0项。

    页表目录、二级页表和各虚拟页面对应关系如图

    1555577191762

    页表目录中:

    第0个页表项指向第0个二级页表,第0个二级页表映射第0-1023个虚拟页面,每一个条目记载该虚拟页面映射的物理页面的地址。关联第0个二级页表的所有虚拟地址la,其PDX(la)必为0,PDX(la)为0-FFF

    第1个页表项指向第1个二级页表,第1个二级页表映射第1024-2047个虚拟页面。关联第1个二级页表的所有虚拟地址la,其PDX(la)必为1,PDX(la)为0-FFF

    ......

    二级页表项访问

    以访问uvpt[0]举例,假设当前页表目录为pgdir

    uvpt[0]的虚拟地址为0xef400000,二进制为1110111101 0000000000 000000000000,其中第一部分是pdx=1110111101,第二部分是ptx=0,第三部分是pgoff=0

    当访问uvpt[0]时:

    1. 取出虚拟地址的PDX,查找页表目录的第pdx项,其值为pgdir[PDX(UVPT)],指向当前页表目录所在的页面,因此找到的二级目录是页表目录
    2. 取出PTX,查找页表目录的第ptx项(第0项),得到第0个二级目录所在的页面
    3. 取出PGOFF,查找页面的第pgoff项(第0项),得到第0个二级目录的第0项,其值是一个页表项,对应第0个页面

    可以看出若访问uvpt[n],若将其虚拟地址拆分为pdx, ptx, pgoff, 则能得到虚拟页面编号N=n=ptx*1024+pgoff=(ptx<<12)+pgoff,因此访问uvpt[n]的值能得到第n个虚拟页面的页表项

    页表目录项访问

    页表目录项访问的过程与二级页表项访问类似

    以访问uvpd[0]举例,假设当前页表目录为pgdir

    uvpd[0]的虚拟地址为UVPT+(UVPT>>12)*4,同上拆成三部分,其中第一部分是pdx=1110111101,第二部分是ptx=(UVPT>>12)*4>>12,第三部分是pgoff=0

    当访问uvpd[0]时:

    1. 取出虚拟地址的PDX,查找页表目录的第pdx项,其值为pgdir[PDX(UVPT)],指向当前页表目录所在的页面,因此找到的二级目录是页表目录
    2. 取出PTX,查找页表目录的第ptx项(第(UVPT>>12)*4>>12项),这个表项还是指向页表目录所在的页面
    3. 取出PGOFF,查找页表目录的的第pgoff个表项(第0项)

    以此类推,uvpd[n](0<=n<1024)就是页表目录的第n个表项

    与访问uvpt[n]相比,其实就是第2个步骤回绕了一下,导致三步查询得到的是目录的表项

    与通常的寻址方式类比

    通常寻址:

      cr3            PDX             PTX            PGOFF  
    ------->页表目录---------二级页表-------->物理页面-------->值
    

    uvpt[n]

      cr3            PDX             PTX            PGOFF  
    ------->页表目录---------页表目录-------->二级页表-------->二级页表项
    

    uvpd[n]

      cr3            PDX             PTX            PGOFF  
    ------->页表目录---------页表目录-------->页表目录-------->目录表项
    
  • 相关阅读:
    利用CSS计数函数counter()实现计数
    弹跳加载动画特效Bouncing loader
    HTML页面中解决内容元素随窗口变化布局变乱问题
    CSS中列表项list样式
    框模型中设置内容区域元素占地尺寸box-sizing属性
    PHP100视频教程-->视频下载
    HTML页面中5种超酷的伪类选择器:hover效果
    HTML中获取input中单选按钮radio数据(性别例子)
    HTML中 DOM操作的Document 对象详解(收藏)
    14、输入一个链表,从尾到头打印链表每个节点的值。
  • 原文地址:https://www.cnblogs.com/sssaltyfish/p/10731406.html
Copyright © 2011-2022 走看看