在MIT-JOS lab4的实验中,为了可以在用户态自定义处理页面错误,咱们必需要知道操做的页面的属性(是否当前用户具备读写权限、是否copy on write页面),这就须要查询指向当前物理页面的页表项和目录表项获取它的属性app
在以前的实验中,咱们已经经过e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) | PTE_P | PTE_U;
修改UVPT
的目录表项,用此操做容许用户读取任一页面的页表项,但没有对其进行详细解释,所以在lab4的应用中遇到了一些障碍:不知道具体是怎么用UVPT
定位到一个页面对应的页表项。在这里,将对这个进行详细解释布局
解释原理前,首先列出各变量和宏的定义,以帮助说明和理解:spa
uvpt
:pte_t uvpt[] = UVPT;
uvpd
:pde_t uvpd[] = UVPT+(UVPT>>12)*4;
对线性地址la
的分解以下:code
// 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
是第几个虚拟页面blog
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个页表项,这一段足够索引到全部页表项。该段地址以只读权限开放给用户态的程序three
首先要明确一点,虽然一个虚拟页面映射到哪一个物理页面是随系统分配的,但虚拟页面在页表中的结构老是固定的,例如第0个虚拟页面地址老是0-FFF,它老是对应页表目录的第0项和第0个二级页表的第0项。内存
页表目录、二级页表和各虚拟页面对应关系如图it
页表目录中:class
第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]
时:
pgdir[PDX(UVPT)]
,指向当前页表目录所在的页面,所以找到的二级目录是页表目录能够看出若访问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]
时:
pgdir[PDX(UVPT)]
,指向当前页表目录所在的页面,所以找到的二级目录是页表目录以此类推,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 ------->页表目录---------页表目录-------->页表目录-------->目录表项