x86内存管理机制--分页机制详析

分页机制

x86的分页机制是更加粒度化的内存管理机制,与分段机制将内存划分成以基地址和长度描述的多个段进行管理不同,分页机制是用粒度化的单位页来管理线性地址空间和物理地址空间。x86架构下一个典型的页大小是4KB,则一个4GB的虚拟地址空间可以划分成1024x1024个页面。物理地址空间划分同理。x86架构允许大于4KB的页面大小,这里只介绍4KB的页面管理机制。

分页机制让现代操作系统中的虚拟内存机制成为可能,感谢这种机制,一个页面可以存在于物理内存中,也可以存放在磁盘的交换区域中。程序可以使用比物理内存更大的内存区域。分页机制的核心思想是通过页表将线性地址转换成为物理地址,并配合旁路转换缓冲区来加速地址转换过程。操作系统在启动过程中,通过将CR0寄存器的PG位置1来启动分页机制。分页机制主要由页表、CR3寄存器、和TLB三个部件构成。

页表Page Table是用于将线性地址转换成物理地址的主要数据结构。一个地址对齐到页边界后的值称为页帧号,它实际是该地址所在页面的基地址。线性地址对应的也帧号即虚拟页帧号VFN,物理地址对应的页帧号即物理地址页帧号PFN 或机器页帧号。故也可以认为,页表是存储VFN到PFN映射的数据结构。4KB大小的页面使用两级页表。

页目录项pageDirectoryEntry 包含页表的物理地址。页目录项存放在页目录中。CPU使用线性地址的22-31位索引页目录,以获得该线性地址对应的页目录项。每个页目录项为4B大小,故页目录占用一个4KB大小的物理页面,共包含1024的页目录项。

页表项PageTableEntry 页表项包含该线性地址对应的PFN。页表项存放在页表中。CPU使用12-21位索引页表,获得该线性地址对应的页表项。通过将线性地址的0-11位偏移量和基地址相加,就可以得到线性地址对应的物理地址。页表项为4B大小,故页表包含1024个页表项,占用也个4KB页面。

TLB

为了提高地址转换效率,x86架构使用TLB对最近用到的页面映射进行缓存,当CPU访问某个线性地址,其所在页面的映射存在于TLB中时,无须查找页表即可进行地址转换。很多教材都说TLB存放的是线性地址到物理地址的转换,准确地说从VFN到PFN的转换。也就是说,CPU从TLB获得一个线性地址对应的PFN后,仍然要和线性地址的偏移相加,才能得到最后的物理地址。而非直接从TLB中获得物理地址。

TLB作为缓存,其能存放的映射条目是有限的,当TLB中没有空闲条目可用时,替换哪一个旧条目由CPU决定。TLB也存在缓存一致性的问题,这主要是指TLB中的映射条目和页表中的映射条目的一致性。当操作系统对页表进行修改后,要负责对TLB中对应的条目或者整个TLB进行刷新。从软件的角度来看,x86提供了两种方式刷新TLB:

1、更新CR3:此操作可以导致TLB被整体刷新,TLB中所有映射条目失效。操作系统将当前CR3中的值重新写回CR3以刷新整个TLB。新进程的页目录基地址会写入CR3而使老进程在TLB中的条目失效。

2、INVLPG指令:这是一种更细粒度的刷新,操作系统可以用它对TLB中单独的页目录项、页表项进行刷新。这通常是在操作系统修改页表后进行的。

前面已经总结过逻辑地址转换线性地址的过程,这里再总结一下CPU使用分页机制,将线性地址转换成物理地址的过程:

(1)、CPU访问一个线性地址映射在TLB中调到(6)。如果映射不存在于TLB中,我们称为一次TLB Miss (TLB缺失)发生,进行下一步。

(2)查找页表,页面在物理内存中调到(4),不再进行下一步。

(3)操作系统的缺页处理函数接管,通常会进行如下操作a、将页面从磁盘复制到物理内存中;b、更改对应的页表项,设置P位为1,并对其他字段进行相应的设置;c、刷新TLB中对应的页表项;d、从缺页错误处理函数中返回。

(4)到这一步,页面已经存在于物理内存中,并且页表已经包含该映射。此时,重新执行引发TLBMiss的指令。
(5)TLB Miss再次发生,CPU重新查页表,把对应的映射插入到TLB中。

(6)到这一步,TLB已经包含了该线性地址对应的PFN。通过将线性地址中的偏移部分和PFN相加,就得到相应的物理地址。

猜你喜欢

转载自blog.csdn.net/d1306937299/article/details/87981860