0 0

第 3 版 · OCR 辅助 · 原书检索 · 文字用于定位,公式与图表请回原页核验 · 本次导入快照

### 0 0
null
1
vm_prot
0x804b
数据段
0x1
vm flags
0x2
0x804a
120
0x8049
只读代码段
0x804b
vm_end
0x8048
vm_start
vm prot
vm_flags
0xfmr[
0
vm next
页表
图7.41 存储管理的总体结构
从图7.41可以看出,存储管理需要计算机系统各层次相互协调完成,它与操作系统、链
第7章
257


<!-- page: 275 -->

计算机组成与系统结构(第3版)
258
接器和CPU硬件等多个系统核心层都有关系。
Linux操作系统内核为每个进程维护一个进程描述符,数据类型为task_struct结构,
其中记录了内核运行该进程所需要的所有信息,如进程ID、指向用户栈的指针、可执行目标
文件的文件名等,并可对进程的虚拟地址空间中的区域(area)进行描述。这些区域是指在
虚拟地址空间中的一个有内容的(已分配的)连续区块,包括图7.39中的只读代码区域、可
读写数据区域、运行时堆、用户栈、共享库等。task_struct结构中有个指针 mm指向一个
mm_struct结构。mm_struct 描述了对应进程虚拟存储空间的当前状态,其中,有一个字段
是 pgd,它指向对应进程的第一级页表(页目录表)的首地址。mm_struct 中还有一个字段
mmap,它指向一个由 vm_area_struct 结构构成的链表表头。
如图7.41所示,每个 vm_area_struct 结构描述了对应进程虚拟存储空间中的一个区
域,可通过系统调用函数mmap()生成,vm_area_struct 中部分字段如下。
(1)vm_start:指向区域的开始处。
(2)vm_end:指向区域的结束处。
(3)vm_prot:描述区域包含的所有页面的访问权限。
(4)vm_flags:描述区域包含页面是否与其他进程共享等。
(5)vm_next:指向链表下一个 vm_area_struct。
在生成可执行文件时,链接器会在可执行文件中生成一个程序头表,用于记录可执行文
件中的信息如何映射到对应进程的虚拟地址空间中。当加载可执行文件时,操作系统根据
可执行文件中的程序头表,通过调用mmap()函数,生成相应进程描述符中关于进程的虚拟
地址空间映像(图7.41中的 vm_area_struct链表),以确定每个可分配段(如只读代码段、可
读写数据段)在虚拟地址空间中的区域位置及其读写属性等信息,并生成对应页表项的初始
信息,初始页表项中装入位P设置为0,存放位置指向外存中的页面所在处。
在进程执行过程中,CPU 第一次访问进程中的代码和数据时,因为代码和数据不在主
存,所以会发生缺页异常;操作系统在处理缺页异常的过程中,将外存中的代码或数据页面
装入所分配的主存页框中,并修改相应页表项,例如,在图7.41中虚拟页号(即 VP#)为
0x804b的页所对应的页表项中,将存放位置(即页框号 PF#)改为主存页框号120,将装入
位P设置为1。这样,以后再次访问这些信息时,就可以根据页表将虚拟地址转换为主存的
物理地址,然后到主存页框中访问信息。
分页方式下,每个区域应占一个页大小的整数倍长度,而可执行文件中的只读数据段和
可读可写数据段不可能正好是页大小的整数倍,因而,最后一个页面中没有信息的地方将补
足0,以使其正好占用一个主存页框。
3)地址转换
对于采用虚存机制的系统,指令中给出的地址是虚拟地址,所以,CPU执行指令时,首
先要将虚拟地址转换为主存物理地址,才能到主存取指令和数据。地址转换(address
translation)工作由 CPU 中的存储器管理部件(MMU)来完成。
由于页大小是2的n次幂,所以,每一页的起点都落在低位字段为零的地址上。虚拟地
址分为两个字段:高位字段为虚拟页号(虚页号或逻辑页号);低位字段为页内偏移地址(简
称页内地址)。主存物理地址也分为两个字段:高位字段为物理页号;低位字段为页内偏移
地址。由于虚拟页和物理页(页框)的大小一样,所以两者的页内偏移地址相等。


<!-- page: 276 -->

存储器层次结构
分页式虚拟存储管理方式下,地址变换过程如图7.42所示。首先根据页表基址寄存器
的内容,找到主存中对应的页表起始位置(即页表基地址),然后将虚拟地址高位字段中的虚
页号作为索引,找到对应的页表项,若装入位为1,则取出物理页号,和虚拟地址中的页内地
址拼接,形成访问主存时实际的物理地址;若装入位为0,则说明缺页,需要操作系统进行缺
页处理。
页表基址寄存器
虚拟页号页内地址
页表基地址
00000010
1010110
虚拟地址
①
②
装入位
物理页号
④
1
10101
③
0
*****
1
11010
### 11010 1010110
物理地址
1
00101
物理页号 页内地址
0
*****
:
页表
图 7.42 分页式虚存的地址转换
4)快表
从上述地址转换过程可看出,访存时首先要到主存查页表,然后才能根据转换得到的物
理地址访问主存。如果缺页,则还要进行页面替换、页表修改等,访问主存的次数就更多了。
因此,采用虚拟存储器机制后,使得访存次数增加了。为了减少访存次数,往往把页表中最
活跃的几个页表项复制到高速缓存中,这种在高速缓存中的页表项组成的页表称为后备转
换缓冲器(translation lookaside buffer,TLB),通常称为快表,相应地称主存中的页表为
慢表。
这样,在地址转换时,首先到快表中查页表项,如果命中,则无须访问主存中的页表。因
此,使用快表是减少访存时间开销的有效方法。
快表比页表小得多,为提高命中率,快表通常具有较高的关联度,大多采用全相联或组
相联方式。每个表项的内容由页表项内容加上一个 TLB标记字段组成,TLB标记字段用
来表示该表项取自页表中哪个虚拟页对应的页表项,因此,TLB标记字段的内容在全相联
方式下就是该页表项对应的虚拟页号;组相联方式下则是对应虚拟页号中的高位部分,而虚
拟页号的低位部分作为 TLB组索引用于选择 TLB组。
图7.43是一个具有 TLB和 cache的多级层次化存储系统示意图,图中 TLB和 cache
都采用组相联映射方式。
在图7.43中,CPU给出的是一个 32 位的虚拟地址,首先,由CPU中的 MMU 进行虚
拟地址到物理地址的转换,然后由处理cache的硬件根据物理地址进行存储访问。
MMU对TLB查表时,20位的虚拟页号被分成标记(tag)和组索引两部分,首先由组索
引确定在 TLB的哪一组进行查找。查找时将虚拟页号的标记部分与 TLB中该组每个标记
字段同时进行比较,若有某个相等且对应有效位V为1,则TLB命中,此时,可直接通过
TLB进行地址转换;否则TLB缺失,此时,需要访问主存去查慢表。图中所示的是两级页
第7章
259


<!-- page: 277 -->

计算机组成与系统结构(第3版)
260
主存
页目录
页表
物理地址
物理页号
页内地址
页目录索引
页表素引
虚拟页号(20位)
页内地址(12)位
虚拟地址
=====
标记(tag)
组索引
VTLB标记(tag)
物理页号
V TLB标记(tag)
物理页号
TLB
TLB命中
MUX
TLB命中
cache
物理地址
物理页号
页内地址
标记(tag)
组索引
块内地址
V
标记(tag)
数据块
V
标记(tag)
数据块
cache 命中
MUX
cache 命中
数据块
字或字节
图7.43 TLB和 cache的访问过程


<!-- page: 278 -->

存储器层次结构
表方式,虚拟页号被分成页目录索引和页表索引两部分,根据这两部分可得到对应的页表
项,从而进行地址转换,并将对应页表项的内容送入TLB形成一个新的TLB表项,同时,将
虚拟页号的高位部分作为TLB标记填入新的TLB表项中。若 TLB已满,还要进行 TLB
替换,为降低替换算法开销,TLB常采用随机替换策略。
在 MMU完成地址转换后,cache硬件根据映射方式将转换得到的主存物理地址划分
成多个字段,然后,根据 cache索引,找到对应的cache行或 cache组,将对应各cache行中的
标记与物理地址中的高位地址进行比较,若相等且对应有效位为1,则 cache命中,此时,根
据块内地址取出对应的字,需要的话,再根据字节偏移量从字中取出相应字节送CPU。
目前 TLB的一些典型指标为:TLB大小为16~512项,块大小为1~2项(每个表项
4~8B),命中时间为0.5~1个时钟周期,缺失损失为10~100个时钟周期,命中率为
90??99??
5)CPU 访存过程
在一个具有 cache 和虚拟存储器的系统中,CPU 的一次访存操作可能涉及TLB、页表、
cache、主存和磁盘的访问,其访问过程如图7.44所示。
CPU给出虚拟地址VA
TLB缺失
不
对应页表项
在TLB中
是
访问主存中的页表
TLB 缺失处理
将VA 转换为物理地址 PA
否
缺页
访问页面在
主存中?
是
更新 TLB 并将VA 转换为物理地址 PA
对应主存块
在cache中?
是
主存中存在
空闲页框?
是
缺页处理
否
从主存换出一页
从磁盘读出一页到主存
更新页表和 TLB
cache 缺失
否
从 cache 替换出一块
否
cache中存在
空闲行?
是
cache 缺失处理
主存块送 cache,并
置标记和有效位
访问 cache 存取数据
图7.44 CPU访存过程
从图7.44可以看出,CPU访存过程中存在以下3种缺失情况。
(1)TLB缺失(TLB miss):要访问的虚拟页对应的页表项不在TLB中。
(2)cache 缺失(cache miss):要访问的主存块不在 cache 中。
(3)缺页(page miss):要访问的虚拟页不在主存中。
表7.3给出了3种缺失的几种组合情况。
第7章
261


<!-- page: 279 -->

计算机组成与系统结构(第3版)
表 7.3 TLB、page、cache 3 种缺失组合
序号
TLB
page
cache
说明
262
1
hit
hit
hit
可能,TLB命中则页一定命中,信息在主存,就可能在 cache 中
2
hit
hit
miss
可能,TLB命中则页一定命中,信息在主存,但可能不在 cache 中
3
miss
hit
hit
可能,TLB缺失但页可能命中,信息在主存,就可能在 cache 中
4
miss
hit
miss
可能,TLB缺失但页可能命中,信息在主存,但可能不在 cache 中
5
miss
miss
miss
可能,TLB缺失,则页也可能缺失,信息不在主存,一定也不在cache中
6
hit
miss
miss
不可能,页缺失,说明信息不在主存,TLB中一定没有该页表项
7
hit
miss
hit
不可能,页缺失,说明信息不在主存,TLB中一定没有该页表项
8
miss
miss
hit
不可能,页缺失,说明信息不在主存,cache 中一定也没有该信息
很显然,最好的情况是第1种组合,此时,无须访问主存;第2种和第3种两种组合都需
要访问一次主存;第4种组合要访问两次主存;第5种组合会发生“缺页”异常,需访问磁盘,
并至少访问主存2次。
cache 缺失处理由硬件完成;缺页处理由软件完成,操作系统通过缺页异常处理程序来
实现;而对于TLB缺失,则既可以用硬件也可以用软件来处理。用软件方式处理时,操作系
统通过专门的TLB缺失异常处理程序来实现。
对于分页式虚拟存储器,其页面的起点和终点地址固定。因此,实现简单,开销少。但
是,由于页面不是逻辑上独立的实体,因此,对于那些不采用对齐方式存储的计算机来说,可
能会出现一个数据或一条指令分跨在不同页面等问题,使处理、管理、保护和共享等都不方
便。采用下面介绍的分段式虚拟存储器就可避免这种情况的发生。
2.分段式虚拟存储器
根据程序的模块化性质,可按程序的逻辑结构划分成多个相对独立的部分,例如过程、
数据表、数据阵列等。这些相对独立的部分被称为段,它们作为独立的逻辑单位可以被其他
程序段调用,形成段间连接,从而产生规模较大的程序。段通常有段名、段起点、段长等。段
名可用用户名、数据结构名或段号标识,以便于程序的编写、编译器的优化、链接和操作系统
的调度管理等。
可以把段作为基本信息单位在主存和外存之间传送和定位。分段方式下,将主存空间
按实际程序中的段来划分,每个段在主存中的位置记录在段表中,段的长度可变,所以段表
中需有长度指示,即段长。每个进程有一个段表,每个段在段表中有一个段表项,用来指明
对应段在主存中的位置、段长、访问权限、使用和装入情况等。段表本身也是一个可再定位
段,可以存在外存中,需要时调入主存,但一般驻留在主存中。
在分段式虚拟存储器系统中,虚拟地址由段号和段内地址组成。通过段表把虚拟地址
变换成主存物理地址,其变换过程如图7.45所示。
每个进程的段表在主存的首地址都存放在段表基址寄存器中,根据虚拟地址中的段号,
可找到对应段表项,以检查是否存在以下3种异常情况。
(1)缺段(段不存在):装入位=0。
(2)地址越界:偏移量超出最大段长。


<!-- page: 280 -->

存储器层次结构
段表基址寄存器
段表基地址
虚拟地址
段号
段内地址
段号 段首址
装入位
段长
0
1
2
n
段表(在主存中)
物理地址
图7.45 分段式虚存的地址转换
(3)访问越权:操作方式与指定访问权限不符。
若发生以上3种情况,则调用相应的异常处理程序,否则,将段表项中的段首址与虚拟
地址中的段内地址相加,生成访问主存时的物理地址。
因为段本身是程序的逻辑结构所决定的一些独立部分,因而分段对程序员(实际上是编
译器)来说是不透明的;而分页方式则对编译器透明,即编译器不需知道程序如何分页。
分段式管理系统的优点是段的分界与程序的自然分界相对应;段的逻辑独立性使它易
于编译、管理、修改和保护,也便于多道程序共享;某些类型的段(如堆、栈、队列等)具有动态
可变长度,允许自由调度以便有效利用主存空间。但是,由于段的长度各不相同,段的起点
和终点不定,给主存空间分配带来麻烦,而且容易在主存中留下许多未分配的零碎空间,造
成浪费。
分段式和分页式存储管理各有优缺点,因此可采用两者相结合的段页式存储管理方式。
3.段页式虚拟存储器
在段页式虚拟存储器中,程序按模块分段,段内再分页,用段表和页表(每段一个页表)
进行两级定位管理。段表中每个表项对应一个段,每个段表项中包含一个指向该段页表起
始位置的指针,以及该段其他的控制和存储保护信息;由页表指明该段各页在主存中的位置
以及是否装入、修改等状态信息。
程序的调入调出按页进行,但它又可以按段实现共享和保护。因此,它兼有分页式和分
段式的优点。它的缺点是在地址转换过程中需要多次查表。
“7.6.4存储保护
为避免主存中多道程序相互干扰,防止某进程出错而影响其他进程的正确性或某进程
非法访问其他进程的代码或数据区,应该对每个进程进行存储保护。
为了对操作系统的存储保护提供支持,硬件必须具有以下3种基本功能。
(1)使部分CPU状态只能由操作系统内核程序写而用户进程只能读不能写或者根本
不能访问。
例如,对于页表首地址、TLB内容等,只有操作系统内核程序才能用特殊指令(一般称
为管态指令或特权指令)来写。常用的特权指令有刷新 cache、刷新 TLB、退出异常/中断处
理、停止处理器执行等。
第7章
263


<!-- page: 281 -->

计算机组成与系统结构(第3版)
264
(2)支持至少两种特权模式。
操作系统内核程序需要比用户程序具有更多的特权,例如,内核程序可以执行用户程序
不能执行的特权指令,内核程序可以访问用户程序不能访问的存储空间等,为此,需要为内
核程序和用户程序设置不同的特权级别或运行模式。
执行内核程序时处理器所处的模式称为监管模式(supervisor mode)、内核模式(kernel
mode)、超级用户模式或管理程序状态(简称为管态、管理态、内核态或核心态);执行用户程
序时处理器所处的模式称为用户模式(user mode)、用户状态或目标程序状态(简称为目态
或用户态),
例如,RISC-V架构定义了3种特权模式,除了上述提到的监管模式(S模式)和用户模
式(U模式)以外,还定义了权限更高的机器模式(M模式)。
需要说明的是,这里的特权模式(也称为特权级)与有些架构的工作模式的含义不同。
例如,IA-32处理器的工作模式有实地址模式和保护模式,它们与特权级的含义不同,但是,
工作模式和特权级之间具有非常密切的关系。例如,IA-32 处理器工作在实地址模式下不
区分特权级,只有在保护模式下才区分特权级。IA-32保护模式下支持4个特权级,但通常
操作系统只使用第0级(监管模式,即内核态)和第3级(用户模式,即用户态)。
(3)提供让处理器核在不同特权模式之间相互转换的机制。
通常,用户模式下可以通过系统调用(执行自陷指令)转入更高特权级别执行。同样,异
常/中断的响应过程也可使处理器从用户模式转到更高特权模式执行。异常/中断处理程序
中最后的返回指令(return from exception)可使处理器从更高特权模式转到用户模式。
例如,RISC-V中可通过执行 mret指令从机器模式返回原模式,或通过执行sret 指令
从监管模式返回原模式。“退出异常/中断”指令mret和sret是特权指令,mret只能在 M
模式中执行,sret只能在M模式或S模式中执行,它们均不能在U模式中执行。
硬件通过提供相应的控制状态寄存器(如 RISC-V中的 CSR)、专门的“自陷”指令以及
各种特权指令等,和操作系统一起实现上述3个功能。通过这些功能,并把页表保存在操作
系统内核的地址空间中,禁止用户进程访问页表,以确保用户进程只能访问由操作系统分配
的存储空间。
以下简要说明 RISC-V架构提供的3种不同特权模式组合系统下的存储保护机制。
1.仅支持M模式的系统
机器模式(M模式)是RISC-V中硬件线程(hart)可以执行的最高特权模式。在 M模
式下运行的 hart对内存、I/O和一些对于启动和配置系统来说必要的底层功能有着完全的
使用权。
最简单的 RISC-V微控制器仅支持M模式。这种系统中,所有程序都在M模式下执
行,因而所有代码都可直接访问系统中的重要信息,因此,这种系统易受到不可信代码的控
制和攻击,只能用于安全性和可靠性要求不高的场合。
2.支持 M模式和U模式的系统
安全的 RISC-V嵌入式系统一般都属于这种系统。通过将不可信代码限制在较低特权
的U模式下执行,来保证系统的重要信息得到保护。
在这种系统中,处理器具有物理内存保护(physical memory protection,PMP)功能,允
许M模式指定U模式可以访问的物理内存地址空间范围。支持PMP功能需要定义8~16


<!-- page: 282 -->

存储器层次结构
个地址寄存器,以及相应的配置寄存器,通过配置寄存器可以设置对相应内存地址范围的
读、写和执行权限。在U模式下,如果处理器在取指令或执行load/store指令时,发生了与
配置寄存器设置的权限不相符的操作,则会引起异常。
在这种系统中,一旦用户程序在U模式下发生异常(如访问了不该访问的存储空间),
或者需要使用重要的底层功能或访问重要的信息时,都必须从U模式转到M模式下执行,
而且只有在M模式下才能执行级别较高的特权指令。这样就避免了不可信代码对系统的
破坏。
3.支持M模式、S模式和U模式的系统
前面所述的两种系统都不能支持分页式虚拟存储管理机制。为了实现现代操作系统的
功能,处理器必须支持具有分页虚拟内存功能的监管模式(S模式)。S模式比U模式权限
高,但比M模式低。与U模式一样,S模式下运行的代码不能使用M模式下的 CSR 寄存
器和指令。
默认情况下,任何特权模式下发生异常/中断时,控制权都会被移交到M模式的异常/
中断处理程序。但是,通常操作系统的大多数异常/中断都应该在S模式下处理。为了避
免从 M模式再转S模式而带来的额外开销,RISC-V提供了一种异常/中断委托机制。通
过该机制可以选择性地直接将异常和中断交给 S模式处理,而完全绕过 M模式。RISC-V
规定,控制权不会从高特权模式移交给较低特权模式处理,即在M模式下发生的异常总是
在M模式下处理,S模式下发生的异常,只可能在M或S模式下处理,不可能移交到U模
式下处理。
S模式提供了一种传统的页式虚拟存储管理机制。RISC-V的分页方案以SvX 的模式
命名,其中,X是虚拟地址的位数。RV32的分页方案Sv32支持4GB的虚拟空间,每个基本
页的大小为4KB,因而虚拟地址(VA)为32位,其中,页内地址(offset)占12位,虚页号
(VPN)占20位。4GB空间共有4GB/4KB=22°=1M个页,划分为1K个子空间,每个子空
间占1K个页面,因而虚页号VPN划分为各占10位的VPN[1]和VPN[2]。采用两级页表
方式,第一级是页目录表,第二级是真正的页表。
每个页目录项(PDE)和页表项(PTE)都是32位,其内容如图7.46所示。
31
2019
### 109 8 7 6 5 4 3
2
1
0
wR√
PPN[1]
PPN[0
RSW D A Gux
12
10
2
1
1
图7.46 RV32 Sv32 页表项
页表项中从右到左各字段的含义如下。
(1)V:有效位(或存在位)。
V=0,表示对应页不在主存,发生缺页故障(page fault)。
(2)R、W、X:存取权限位。
分别表示该页是否可读、可写和可执行。当指令执行时实际发生的操作与存取权限发
生矛盾,则会引起访存故障或取指令故障。若三位全为0,则说明这是页目录项,其中PPN
存放的是所指向的下一级页表所在的物理页(即页框)号。
(3)U:是否是在用户模式下可访问。
第7章
265


<!-- page: 283 -->

计算机组成与系统结构(第3版)
266
若U=0,则U模式下不能访问此页面,但S模式可以;若U=1,则U模式下能访问,而
默认S模式不能。在不能访问时,若进行了访存操作,则会引起相应的访存故障。默认S模
式下不能访问U=1的页面,这样可以防止恶意程序“哄骗”操作系统窃取其他程序的数据。
(4)G:指定全局映射。
全局映射指存在于整个地址空间的映射,通常用于操作系统自身使用的页面。对于页
目录项,若G=1,则说明其下一级所有页表项都是全局映射。注意,将全局映射标记为非全
局映射只会降低性能,而将非全局映射标记为全局映射则会发生相应的访存故障。
(5)A:访问位,
记录自上一次 A 位被清除以来,该页是否被访问过。
(6)D:脏位。
记录自上一次 D位被清除以来,该页是否被写过。
(7)RSW:留给操作系统使用,硬件可忽略。
(8)PPN:物理页(页框)号。
若是页表项,则给出虚拟页所在的页框号;若是页目录项,则给出下一级页表所在的页
框号。
虚拟地址转换为物理地址的过程如图7.47所示。
31
2221
1211
0
VA
VPN[1]
VPN[0]
offset
SATP
33
页目录表
PDE
页表
PTE
1211
0
PA
PPN
offset
图7.47 Sv32中地址转换过程
图7.47中的SATP(supervisor address translation and protection)是 S模式下的一个
CSR寄存器,其中,有一个 MODE字段可以设置是否开启分页模式以及支持多少位虚拟地
址,在开启分页模式的情况下,PPN字段用于指出页目录表的页框号。Sv32分页模式下,
CPU 进行虚拟地址到物理地址转换的过程如下。
第一步,读取位于主存地址(satp.PPN×4096+VA[31:22]×4)处的页目录项(PDE)。
第二步,读取位于主存地址(PDE.PPN×4096+VA[21:12]×4)的页表项(PTE)。
第三步,页表项中22位的 PPN字段和VA中的页内偏移地址(offset)组成34位物理
地址(PTE.PPN×4096+VA[11:0])。
在进行地址转换过程中,处理器会根据页表项的内容进行各种异常情况检查。例如,若
V=0,则引起缺页故障;若实际操作与R、W、X指定的操作不符,则引起访存故障或取指令


<!-- page: 284 -->

存储器层次结构
故障(有时统称为保护错)。通过这种方式系统便可进行相应的存储保护。