|| 版权声明:本文为博主原创文章,未经博主允许不得转载。
一、前言
在我们进行程序开发的时候,一般情况下,是不需要管理内存的,也不需要操心内存够不够用,其实,这就是分页机制给我们带来的好处。它是实现虚拟存储的关键,位于线性地址与物理地址之间,在使用这种内存分页管理方法时,每个执行中的进程(任务)可以使用比实际内存容量大得多的连续地址空间。而且当系统内存实际上被分成很多凌乱的块时,它可以建立一个大而连续的内存空间的映象,好让程序不用操心和管理这些分散的内存块。分页机制增强了分段机制的性能。页地址变换是建立在段变换基础之上的。因为,段管理机制对于Intel处理器来说是最基本的,任何时候都无法关闭。所以即使启用了页管理功能,分段机制依然是起作用的,段部件也依然工作。
二、页表结构
那么到底如何使用分页机制呢?通过设置cr0的PG位可以开启分页机制。页大小是4K,并且是4K对齐的。线性地址通过分页机制转换成物理地址的时候,可能某些线性地址是无效的。如果某个线性地址对应的页不存在,那么访问的时候将产生一个异常。
两级页表结构
内存分页管理的基本原理是将整个主内存区域划分成 4096 字节为一页的内存页面。程序申请使用内存时,就以内存页为单位进行分配。上面提到了线性地址经过分页机制的转换变成物理地址,但是没有提到如何转换。其实是通过两个表,一个是页目录表PDE,也叫一级目录,另一个是二级页表PTE。进程的虚拟地址需要首先通过其局部段描述符变换为 CPU 整个线性地址空间中的地址, 然后再使用页目录表 PDE(一级页表)和页表 PTE(二级页表)映射到实际物理地址页上。页表中,每项的大小是32b,其中20b用来存放页面的物理地址,12b用于存放属性信息。页表含有1M个表项,每项4B。第一级表是页目录,存放在1页4k页面中,含有1K个表项。第二级是页表,也是1K个表项。如下图所示:
三、结构
PDE结构
PTE结构
从上图中,可以看出PDE与PTE的结构其实是差不多的,其中属性位包含如下信息:
P——bit0,存在位标志,表示当前条目所指向的页或页表是否在物理内存中;
R/W——bit1,读写位标志,指定一个页或者一组页的读写权限。R/W=0表示只读,R/W=1可读可写;
U/S——bit2,用户/超级用户标志,指定一个页或者一组页的特权级;
PWT——bit3,用于控制对单个页或者页表的Write-back或者Write-through缓冲策略;
PCD——bit4,用于控制对单个页或者页表的缓冲;
A——bit5,表示页或者页表是否被访问;
D——bit6,表示页或者页表是否被写入;
PS——bit7,决定页的大小;
G——bit8,指示全局页;
AVL——保留字段;
保护模式是否开启,取决于cr0的第0位PG。一个页表或者页目录项大小是4B;而开启分页机制以后,存储单元变成了页(不存在说,一部分存储开启了分页机制,另外一部分没有开启分页机制(除非这部分不能通过操作系统访问到))。所以,一个页上含有1024个页表项;一个页目录,对应1K*4K=4M的空间;一个程序有4G的线性地址空间,正好需要1K个页目录来存储,它占用的页表是4M。
另外,页表和页目录表都表项都是32b的,其中地址对应的是20b。处理器会将最近经常用到的页目录和页表项保存在TLB中。而TLB是什么呢?可以简单地理解,TLB就是页表的Cache,其中存储了当前最可能被访问到的页表项,其内容是部分页表项的一个副本。只有在TLB无法完成地址翻译任务时,才会到内存中查询页表,这样就减少了页表查询导致的处理器性能下降。
当页目录或者页表项被修改的时候,对应TLB中的项目也就失效了;当cr3重新加载的时候,所有的TLB都失效了,除非页或页表条目的G位被设置。
上图是CR3的结构,CR3又叫PDBR,就是页目录寄存器。它的高20位将是页目录表首地址的高20位,页目录表的低12位会是零,也就是说,页目录表会是4KB对齐。类似地,PDE中的页表基址以及PTE中的页基址也是用高20位来表示4KB对齐的页表和页。
四、总结
回顾上面讲到的内容不是很多,主要是这部分都是理解系统的基础,包括下面几点:
1.分页的作用,高效率地利用内存,可以运行比物理内存空间更大的程序;
2.分页机制的原理,利用两级页表将内存分割成4KB/页的大小,强制内存对齐提高效率;
3.页表结构,PDE与PTE在内存中各个位的主要作用,表项与页之间的对应关系。
前面几篇分享,都提到很多原理,废话特别多,下篇开始我们将用代码来逐渐说明,希望大家继续关注!!