什么叫做"页",所谓"页",就是一块内存,在80386中,页的大小是固定的4096字节。
在未打开分页机制时,线性地址等同于物理地址,于是可以认为,逻辑地址通过分段机制直接转换成物理地址。但当分页开启时,分段机制将逻辑地址转换成线性地址,线性地址再通过分页机制转换成物理地址。下图为地址转换的流程:
分页机制就像一个函数:
物理地址=f(线性地址)
线性地址中任意一个页都能映射到物理地址中任何一个页,这使得内存管理变得相当灵活。下图是分页机制示意图:
由上图可得转换使用两级页表,第一级叫页目录表,大小为4KB,存储在一个物理页中,每个表项4字节长,共1024个表项。每个表项对应第二级的一个页表,第二级的每个页表也有1024个表项,每个表项对应一个物理页。页目录表简称PDE(Page Direcotry Entry),页表简称PTE(Page Table Entry)
进行转换时,先是从由寄存器cr3指定的页目录中根据线性地址的高10位得到页表地址,然后再页表中根据线性地址的第12到21位得到物理页首地址,将这个首地址加上线性地址低12位便得到了物理地址。
分页机制是否生效的开关位于cr0的最高位PG位。如果PG=1,则分页机制生效。当我们准备好了页目录表和页表,并经cr3指向页目录表之后,只需要置PG位,分页机制就开始工作了。
========================================================================
PDE和PTE:
下图是PDE的结构图:
下图是PTE的结构图:
各位解释如下:
1.P存在位,表示当前条目所指向的页或页表是否在物理内存中。P=0表示页不在内存中,如果处理器试图访问此页,将会产生异常(pag-fault exception #PF);P=1表示在内存中
2.R/W指定一个页或者一组页的读写权限。此位与U/S位和寄存器cr0的WP位相互作用。U/S=0表示系统级别(Supervisor Privilege Level),如果CPL为0、1或2,那么它便是此级别;U/S=1表示用户级别(User Privilege Level),如果CPL位3,那么它便是在此级别。
如果cr0中的WP位0,那么即便用户级(User P.L.)页面的R/W=0,系统级(Supervisor P.L.)程序仍具备读写权限;如果WP位为1,那么系统级(Supervisor P.L.)程序也不能写入用户级(User P.L.)只读页。
3.PWT用于控制对单个页或者页表的缓冲策略。PWT=0时使用Write-back缓冲策略;PWT=1时使用Write-through缓冲策略。当cr0寄存器的CD(Cache-Disable)位被置位时会被忽略。
4.PCD用于控制对单个页或者页表的缓冲,PCD=0可以被缓冲;PCD=1时页或页表不可以被缓冲。
5.A指示页或页表是否被访问。此位往往在页或页表刚刚被加载到物理内存中时被内存管理程序清零,处理器会在第一次访问此页或页面时设置此位。而且,处理器并不会自动清除此位,只有软件能清除它。
6.D指示页或页表是否被写入。此位往往在页或页表刚刚被加载到物理内存中时被内存管理程序清零,处理器会在第一次写入此页或页面时设置此位。而且,处理器并不会自动清除此位,只有软件清除它。
A位和D位都是被内存管理程序用来管理页和页表从物理内存中换入和换出的。
7.PS决定页大小。PS=0时页大小为4KB,PDE指向页表。
8.PAT 页属性表。Pentium III以后的CPU开始支持此位。
9.G指示全局页。如果此位被设置,同时cr4中的PGE位被置,那么此页的页表或页目录条目不会再TLB中变得无效,即便cr3被加载或者任务切换时也是如此。
处理器会将最近常用的页目录表和页表项保存在一个叫做TLB(Translation Lookaside Buffer)的缓冲区中。只有在TLB中找不到被请求页的转换信息时,才会到内存中去寻找。这样大大加快了访问页目录和页表的时间。
当cr3被加载时,所有TLB都会自动无效,除非页或页表条目的G位被设置。
========================================================================
cr3的结构如下图:
cr3又叫做PDBR(Page-Directory Base Register)。它的高20位将是页目录表首地址的高20位,页目录表首地址的低12位会是零,所以页目录表会是4KB对齐的。类似的,PDE中的页表基址(Page-Table Base Address)以及PTE中的页基址(Page Base Address)也是用高20位来表示4KB对齐的页表和页。