一、背景知识
a.重谈地址空间
我们之前已经说过,CPU内部见的地址,以及我们打印出来的地址都是虚拟地址;物理内存加载到CPU,CPU内执行进程创建内核数据结构,页表等,通过页表映射到物理磁盘上;也就是说地址从CPU出来那一刻起,已经变成物理地址
CPU内有两个重要的寄存器cr2,cr3寄存器
-
CR2是一个重要的控制寄存器,主要用于内存管理,特别是与分页机制相关。CR2寄存器通常用于存储导致页错误的线性地址。当处理器启用分页机制时,如果发生页错误(即处理器试图访问一个不在物理内存中的虚拟地址),CR2会保存引起该错误的线性地址。这个地址信息对于操作系统来说非常有用,因为它可以帮助操作系统确定哪个虚拟地址导致了页错误,并采取相应的措施,比如加载所需的页面到物理内存中。
-
CR3寄存器通常被称为页目录基址寄存器(PDBR),它存储的是当前任务页目录的物理地址。页目录是分页机制中的一个数据结构,用于将虚拟地址映射到物理地址。
还有一个非常重要的硬件MMU
内存管理单元(Memory Management Unit,简称MMU)是计算机硬件的一部分,它负责处理虚拟内存到物理内存的映射。MMU是现代操作系统实现内存保护、虚拟内存和多任务处理的关键组件
主要功能:
地址转换:MMU将虚拟地址(由CPU生成的地址)转换为物理地址(实际内存中的地址)。这个过程通常涉及到页表或段表查找。
内存保护:MMU可以限制特定进程对内存的访问,以防止一个进程访问或修改另一个进程的内存空间,从而提高系统的稳定性和安全性。
虚拟内存管理:MMU允许系统使用比物理内存更大的虚拟地址空间。通过将不常用的内存页交换到磁盘(称为交换或分页),MMU帮助操作系统管理更大的工作集。
缓存控制:MMU还负责控制内存访问的缓存行为,例如决定是否启用或禁用缓存。
物理内存是什么样的?
首先我们要知道:OS进行内存管理,不是以字节为单位的,而是以内存块为单位的,默认大小是4KB,系统和磁盘文件进行IO的基本单位是4KB---->8个扇区
我们之前只说页表是用来虚拟地址到物理地址映射的
真正的页表是什么样呢?虚拟地址是如何转换为物理地址的呢?
虚拟地址不就是一个32位的比特位吗?我们把这32位分成10,10,12三个块;第一个块我们用于页目录作为索引,页目录里面存的是页表的地址,第二个块我们用于页表,页表里面指向的页框的起始地址;第三个块有12位比特位,转换成十进制可表示[0,4095],这一部分我们用于页内偏移量,这样32位都用上了,32位的组合就成了一个地址
这样的话页表的大小也就是1024*2KB + 4KB(页目录)
b.理解代码数据划分的本质,虚拟地址的本质是什么
函数有地址吗?---> 有,函数就是一批代码的入口地址
每行代码都有地址,而且同一个函数我们认为地址是连续的!
【问题】那么函数是什么?
-
函数就是连续的代码地址构成代码块,一个函数对应一批的虚拟地址
所以说,虚拟地址本质是一种资源
c.更官方的解释概念
基本分页内存管理方式
【问题】为什么引入基本分页内存管理方式?
➢ 在连续存储管理方式中,固定分区会产生内部碎片,动态分区会产生外部碎片。这两种技术对内存的利用率都比较低
➢ 内存中可能缺少大块的连续空间
外部碎片,是由于大量信息由于先后写入、置换、删除而形成的空间碎片。由于这样的原因形成的空间碎片,我们称之为外部碎片。
内部碎片,是由于存量信息容量与最小存储空间单位不完全相符而造成的空间碎片。
-
页(页面)—— Page
在分页管理中,由于进程在申请内存空间时,是逐个按照块来申请空间的,故进程被分成若干个逻辑块,这些逻辑块被称为页(或页面)。
分页存储管理,是将一个进程的逻辑地址空间分成若干个大小相等的片,称为页面或页,并为各页加以编号,从0开始,如第0页、第1页等
-
页框(页帧)—— Page frame
进程中的页必然要映射到内存中的物理块,即一个页(页面)对应唯一的物理块,这些内存中的块(物理块)称为页框(或页帧)。
内存按页的大小划分为大小相等的区域,称为物理块(物理页面,页框(frame),帧),同样加以编号,如 0#块、1#块等等。
-
页框(页帧)和页面的对应关系
在为进程分配内存时,以块为单位将进程中的若干个页分别装入到多个可以不相邻接的物理块中。
-
页面大小
每个页,也就是进程中的每一块,都有相同的大小,叫做页面大小,为了方便地址转换,一般取2的整数次幂(二进制思想),常见的页面大小是4KB(32位系统)。
-
页表项
页表项是页表的基本构成单元,一个页表项相当于页表的一条记录。页表项由页号和内存的物理块号(就是页框号)构成
-
在分页管理方式中,逻辑地址结构由页号与页内偏移量(页内地址)构成
系统内存= 内存最多页面数 × 页面大小
对于32位系统,系统最多有220个页面,每个页面4KB,则内存大小就等于220 ×4KB,合4GB。
换句话说,一个页表也要必须能够索引到全部页面,因此页表中的页表项个数就是最多页面数。
页面中页表项个数= 内存最多页面数= 2^页号所占位数
用来表示页号占去了20位,那么一个页表就能表示220页表项,假设每个页表项占
用4Bytes空间,那么页表大小是多少呢?2^20×4Bytes = 4MB,一个页表大小就占了4MB这么大的内存空间。
物理地址= 物理块号 × 页面大小 + 页内偏移量
页表
为了能在内存中找到每个页面所对应的物理块。系统又为每个进程建立了一张页面映像表,简称页表。
页表的作用是实现从页号到物理块号的地址映射
在进程地址空间内的所有页(0~n),依次在页表中有一页表项,其中记录了相应页在内存中对应的物理块号.
页表通常存在PCB(进程控制块)中, 进程执行时,页表常驻内存。
-
关于页表的几个重要概念
一个进程对应一张页表,进程的每个页面对应一个页表项;每个页表项 “块号”和其他信息组成
页表记录进程页面和实际存放的内存块之间的映射关系
页表的本质是一个大数组,页号是数组下标,页表项是数组元素,其大小是块号。
地址变换过程
页表大多驻留在内存中
在系统中只设置一个页表寄存器 PTR(Page-Table Register),在其中存放页表在内存的始址和页表的长度。
进程未执行时,页表的始址和页表长度存放在本进程的 PCB 中。
当调度程序调度到某进程时,才将这两个数据装入页表寄存器中。
当进程要访问某个逻辑地址中的数据时,分页地址变换机构会自动地将有效地址(相对地址)
分为页号和页内地址两部分,再以页号为索引去检索页表。查找操作由硬件执行。
-
先将页号与页表长度进行比较,如果页号大于或等于页表长度,则表示本次所访问的地址已超越进程的地址空间。于是,这一错误将被系统发现并产生地址越界中断。
-
若未出现越界错误,则将页表始址与页号和页表项长度的乘积相加,便得到该表项在页
表中的位置,于是可从中得到该页的物理块号,将之装入物理地址寄存器中。
-
与此同时,再将有效地址寄存器中的页内地址送入物理地址寄存器的块内地址字段中。
-
完成从逻辑地址到物理地址的变换。
两级页表的引入
对于一个具有32位逻辑地址空间的分页系统,规定页面大小为4 KB即2^12 B,则在每个进程页表中的页表项可达1兆(2^20)个之多。又因为每个页表项占用一个字节, 故每个进程仅仅其页表就要占用1M的内存空间,而且还要求是连续的。
可以采用这样两个方法来解决这一问题:
① 采用离散分配方式来解决难以找到一块连续的大内存空间的问题:
② 只将当前需要的部分页表项调入内存,其余的页表项仍驻留在磁盘上,需要时再调入。
对于要求连续的内存空间来存放页表的问题,可利用将页表进行分页,并离散地将各个页面分别存放在不同的物理块中的办法来加以解决,同样也要为离散分配的页表再建立一张页表,称为外层页表,在每个页表项中记录了页表页面的物理块号。
二级分页存储管理方式的实现
-
两级页表地址结构
以32 位逻辑地址空间为例来说明,如图所示。当页面大小为 4 KB 时(12 位),若采用一级页表结构,应具有 20 位的页号,即页表项应有 1 兆个;
在采用两级页表结构时,再对页表进行分页,使每页中包含 2^10 (即 1024)个页表项,最多允许有 2^10个页表分页;或者说,外层页表中的外层页内地址 P2为10 位,外层页号 P1也为 10 位。
-
地址变换过程
在地址变换机构中,需要增设一个外层页表寄存器,用于存放外层页表的始址
利用逻辑地址中的外层页号P1作为外层页表的索引,从中找到指定页表分页的始址,利用 P2 作为指定页表分页的索引,找到指定的页表项,其中即含有该页在内存的物理块号P,该块号 P 和页内地址 d 即可构成访问的内存物理地址。
-
地址变换过程
逻辑地址最高10位(二进制编码,如果不是先转换)得到一级页号,
中间10位得到二级页号,
最低12位得到页内偏移。
根据一级页号对应的物理块找到对应的二级页表在物理内存中的位置,
在二级页表中查找二级页号对应的物理块在内存中的位置
之后步骤与“基本分页管理方式”一致