页表

页表结构

分页转换功能由驻留在内存中的表来描述,该表称为页表(page table),存放在物理地址空间中。页表可看做简单的220个物理地址数组。线性到物理地址的映射功能可以简单地看做进行数组查找。线性地址的高20位构成这个数组的索引值,用于选择对应页面的物理(基)地址。线性地址的低12位给出了页面中的偏移量,加上页面的基地址最终形成对应的物理地址。由于页面基地址对齐在4K边界上,因此页面基地址的低12位肯定是0。这意味着高20位的页面基地址和12位偏移量连接组合在一起就能得到对应的物理地址。

页表中每个页表项的大小为32位。由于只需要其中的20位来存放页面的物理基地址,因此剩下的12位可用于存放诸如页面是否存在等的属性信息。如果线性地址索引的页表项被标注为存在的,则表示该项有效,我们可以从中取得页面的物理地址。如果页表项中信息表明(说明、指明)页不存在,那么当访问对应物理页面时就会产生一个异常。

1.两级页表结构

页表含有220(1M)个表项,而每项占用4B。如果作为一个表来存放的话,它们最多将占用4MB的内存。因此为了减少内存占用量,80x86使用了两级表。由此,高20位线性地址到物理地址的转换也被分成两步来进行,每步使用(转换)其中的10bit。

第一级表称为页目录(page directory)。它被存放在1页4K页面中,具有210(1K)个4B长度的表项。这些表项指向对应的二级表。线性地址的最高10位(位31~22)用作一级表(页目录)中的索引值来选择210个二级表之一。

第二级表称为页表(page table),它的长度也是1个页面,最多含有1K个4B的表项。每个4B表项含有相关页面的20位物理基地址。二级页表使用线性地址中间10位(位21~12)作为表项索引值,以获取含有页面20位物理基地址的表项。该20位页面物理基地址和线性地址中的低12位(页内偏移)组合在一起就得到了分页转换过程的输出值,即对应的最终物理地址。

图4-17给出了二级表的查找过程。其中CR3寄存器指定页目录表的基地址。线性地址的高10位用于索引这个页目录表,以获得指向相关第二级页表的指针。线性地址中间10位用于索引二级页表,以获得物理地址的高20位。线性地址的低12位直接作为物理地址低12位,从而组成一个完整的32位物理地址。

 

(点击查看大图)图4-17  线性地址和物理地址之间的变换

 

2.不存在的页表

使用二级表结构,并没有解决需要使用4MB内存来存放页表的问题。实际上,我们把问题搞得有些复杂了。因为我们需要另增一个页面来存放目录表。然而,二级表结构允许页表被分散在内存各个页面中,而不需要保存在连续的4MB内存块中。另外,并不需要为不存在的或线性地址空间未使用部分分配二级页表。虽然目录表页面必须总是存在于物理内存中,但是二级页表可以在需要时再分配。这使得页表结构的大小对应于实际使用的线性地址空间大小。

页目录表中每个表项也有一个存在(present)属性,类似于页表中的表项。页目录表项中的存在属性指明对应的二级页表是否存在。如果目录表项指明对应的二级页表存在,那么通过访问二级表,表查找过程第2步将同如上描述继续下去。如果存在位表明对应的二级表不存在,那么处理器就会产生一个异常来通知操作系统。页目录表项中的存在属性使得操作系统可以根据实际使用的线性地址范围来分配二级页表页面。

目录表项中的存在位还可以用于在虚拟内存中存放二级页表。这意味着在任何时候只有部分二级页表需要存放在物理内存中,而其余的可保存在磁盘上。处于物理内存中页表对应的页目录项将被标注为存在,以表明可用它们进行分页转换。处于磁盘上的页表对应的页目录项将被标注为不存在。由于二级页表不存在而引发的异常会通知操作系统把缺少的页表从磁盘上加载进物理内存。把页表存储在虚拟内存中减少了保存分页转换表所需要的物理内存量。

 

二、页表项格式

 

页目录和页表的表项格式如图4-18所示。其中位31~12含有物理地址的高20位,用于定位物理地址空间中一个页面(也称为页帧)的物理基地址。表项的低12位含有页属性信息。前文已经讨论过存在属性,这里简要说明其余属性的功能和用途。

 

(点击查看大图)图4-18  页目录和页表的表项格式

 

P--位0是存在(Present)标志,用于指明表项对地址转换是否有效。P=1表示有效;P=0表示无效。在页转换过程中,如果说涉及的页目录或页表的表项无效,则会导致一个异常。如果P=0,那么除表示表项无效外,其余位可供程序自由使用,如图4-18b所示。例如,操作系统可以使用这些位来保存已存储在磁盘上的页面的序号。

R/W--位1是读/写(Read/Write)标志。如果等于1,表示页面可以被读、写或执行。如果为0,表示页面只读或可执行。当处理器运行在超级用户特权级(级别0、1或2)时,则R/W位不起作用。页目录项中的R/W位对其所映射的所有页面起作用。

U/S--位2是用户/超级用户(User/Supervisor)标志。如果为1,那么运行在任何特权级上的程序都可以访问该页面。如果为0,那么页面只能被运行在超级用户特权级(0、1或2)上的程序访问。页目录项中的U/S位对其所映射的所有页面起作用。

A--位5是已访问(Accessed)标志。当处理器访问页表项映射的页面时,页表表项的这个标志就会被置为1。当处理器访问页目录表项映射的任何页面时,页目录表项的这个标志就会被置为1。处理器只负责设置该标志,操作系统可通过定期地复位该标志来统计页面的使用情况。

D--位6是页面已被修改(Dirty)标志。当处理器对一个页面执行写操作时,就会设置对应页表表项的D标志。处理器并不会修改页目录项中的D标志。

AVL--该字段保留专供程序使用。处理器不会修改这几位,以后的升级处理器也不会。

----------------------------

 我看很多人都把页表项的结构理解错了,很多书上把页表项分为逻辑上的页号和页框号(也有叫块号的),这容易造成一个误导,以为页表项由页号和页框号构成,但实际上页表项中并没有存储页号,只有20位的页框号,剩的12位应当是附加的控制位(具体大家可以查一查),在计算页表项地址时,要求页表连续并且足够长(2的20次方页,页表项长度4B,对应的是4MB)以映射全部物理地址空间,然后页号和页框号的对应关系就可以用如下公式体现出来:页表项(只含页框号)地址=页表起始地址+页号×页表项长度,而无需多花20位再来存储页号。

<think>嗯,我现在要理解页表的概念和实现。首先,页表应该是操作系统内存管理中的一个部分,特别是在虚拟内存管理里。记得之前学过虚拟内存,它允许程序使用比实际物理内存更大的地址空间,对吧?页表应该是用来映射虚拟地址到物理地址的结构。 页表可能是指页表中的每一个条目,用来记录虚拟页面和物理页框的对应关系。每个页表可能包含物理页框号,还有一些状态,比如是否存在内存中、是否被修改过、访问权限等。比如,当程序访问一个虚拟地址时,操作系统会通过页表找到对应的物理地址。如果该页不在内存中,就会触发缺页中断,然后从磁盘调入。 那页表具体是怎么实现的呢?可能需要考虑每个页表的大小。比如,在32系统里,假设物理地址空间是4GB,那么每个页框的大小通常是4KB,所以物理页框号可能需要20(因为4GB/4KB=1M个页框,即2^20)。再加上一些控制,比如存在、脏、访问权限等,可能每个页表需要32(4字节)。比如,存在占1,读写权限占几,物理页框号占20,剩下的可能用于其他标志。 不过不同的系统可能有不同的设计,比如64系统可能需要更大的页表。另外,多级页表结构可能也会影响页表的实现,比如层次分页可以减少页表的内存占用。例如,x86系统使用多级页表页表的结构可能更复杂,包含指向下一级页表的地址或者物理页框号。 页表的作用应该是实现虚拟地址到物理地址的转换,支持内存保护,比如读写权限,用户态和内核态的访问控制,还有记录页面的使用情况,比如是否被访问过,是否被修改过,这对页面置换算法很重要,比如在需要换出页面时,选择被修改过的页面可能需要写回磁盘,而未被修改的可以直接丢弃。 可能还有引用,用于时钟算法或最近未使用算法。此外,页表中的信息还能帮助处理缺页中断,比如通过存在判断是否需要调入页面。 在实现上,操作系统需要维护每个进程的页表,通常存储在内存中,由MMU(内存管理单元)硬件来加速地址转换。当发生上下文切换时,操作系统会切换页表基址寄存器,指向新进程的页表。这样每个进程都有自己的虚拟地址空间,互不干扰。 不过,如果每个进程的页表都很大,比如在32系统下,每个进程可能有百万级的页表,这会占用很多内存。因此,多级页表页表的紧凑设计就很重要。例如,使用层次化的页表结构,只有实际使用的部分才会分配内存,节省空间。 另外,页表中的权限(如用户/超级visor模式)可以防止用户进程访问内核空间的内存,提高系统安全性。还有,通过共享内存的页表设置,不同进程可以共享同一物理页框,实现进程间通信。 总结一下,页表页表的基本单元,存储了虚拟页到物理页框的映射及相关控制信息,实现地址转换、内存保护和页面管理等功能。实现时需考虑结构、大小、多级分页和硬件支持等因素。</think>### 页表的概念与实现 #### 1. **页表的定义** 页表(Page Table Entry, PTE)是页表中的基本单元,用于记录虚拟页与物理页框(Page Frame)的映射关系及控制信息。每个页表对应一个虚拟页,存储以下关键信息[^2][^3]: - **物理页框号(PFN)**:虚拟页对应的物理内存页框地址。 - **存在(Present Bit)**:标记该页是否已加载到内存中。 - **访问权限**(如读/写/执行权限)。 - **修改(Dirty Bit)**:标记该页是否被修改过(决定换出时是否需要写回磁盘)。 - **其他控制**:如用户/内核模式访问权限、共享标志等。 #### 2. **实现方式** ##### (1)页表结构 以32系统为例,假设页大小为4KB: - 物理页框号占20(可寻址$2^{20}$个页框,覆盖4GB物理内存)。 - 控制占12(包括存在、修改、权限等)。 - 总大小为4字节(32),结构示例如下: $$ \text{物理页框号(20)} \mid \text{保留(12)} \mid \text{存在(1)} \mid \text{读写(1)} \mid \text{用户/内核(1)} $$ ##### (2)多级页表 现代操作系统(如x86)采用多级页表减少内存占用。例如,x86-64使用四级页表: 1. **页全局目录(PGD)** 2. **页上级目录(PUD)** 3. **页中间目录(PMD)** 4. **页表(PT)** 每级页表存储下一级页表的物理地址,最终指向物理页框[^5]。 ##### (3)硬件支持 - **MMU(内存管理单元)**:负责通过页表完成虚拟地址到物理地址的转换。 - **TLB(快表)**:缓存常用页表,加速地址转换[^4]。 #### 3. **核心作用** 1. **地址转换**:将虚拟地址映射到物理地址,支持虚拟内存机制。 2. **内存保护**:通过权限限制非法访问(如用户进程访问内核空间)。 3. **页面置换支持**:记录访问和修改,供页面置换算法(如LRU、Clock)使用[^3]。 4. **共享内存**:多个进程的页表可指向同一物理页框,实现内存共享。 #### 4. **示例:页表在缺页中断中的使用** 当进程访问一个虚拟地址时: 1. MMU查找页表,若存在为0,触发缺页中断。 2. 操作系统从磁盘加载缺失页到物理内存,更新页表的存在和物理页框号。 3. 重新执行指令,完成地址转换。 ```c // 简化的页表结构(Linux内核示例) typedef struct { unsigned int pfn : 20; // 物理页框号 unsigned int present : 1; // 存在 unsigned int writable : 1; // 可写 unsigned int user : 1; // 用户模式可访问 unsigned int dirty : 1; // 修改 } page_table_entry; ``` #### 5. **性能与优化** - **页表大小**:直接影响页表内存占用。64系统可能使用8字节的页表。 - **大页(Huge Page)**:通过增大页大小(如2MB)减少页表层级,提升TLB命中率。 - **反向页表**:以物理页框为索引,减少页表内存消耗(常用于嵌入式系统)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值