31、分页和动态页面分配

01、保护模式下的段式虚拟内存管理

在这里插入图片描述
任务的划分实际上是内存空间的划分。
在这里插入图片描述
内存空间的访问是依靠分段机制进行的,是通过将内存划分为段里来进行的。先在描述符表中定义每个段的描述符,然后通过描述符来访问其对应的内存段。

程序中先将段选择子送入段寄存器sreg中,再使用jmp、call指令进行跳转。其中段选择子的TI位为0表示描述符在GDT中、为1表示描述符在LDT中。
在这里插入图片描述
每个任务的描述符索引是13位,最多2^13=8192个,段内偏移是32位的,段的长度最大是2^32=4GB,则任务的全局部分为2^13 x 2^32 = 2^45 = 32TB,任务的私有部分为2^13 x 2^32 = 2^45 = 32TB,则一个任务理论总大小为64TB。在一个多任务系统中,还有其他多个任务。但是32根地址线最多有4GB字节的物理内存空间。
在这里插入图片描述
上图中,任务的全局部分占据物理内存高2GB、任务的私有部分占据物理内存低2GB。
在这里插入图片描述
开始将所有段的P位清零,表示暂时不在内存中,把要访问的段P位置1,将其调入物理内存中。
在这里插入图片描述
将段1置换到外部磁盘、将段1的P位清零、将段3置换到物理内存、将段3的P位置1。
在这里插入图片描述
下一次访问段1,发现P位为0,首先将其置换到物理内存中、再将段3的P位清零、再将段1的P位置1。使用上述这种方式实现段式虚拟内存管理策略

实际中,段有大有小,不会有2G字节,当内存空间不足时需要进行段的换入换出,置换出当前最少使用的段。在段描述符中有一个特殊的位A,表示已访问位。当处理器访问一个段时,自动将A位置1,由内核进行清零。根据A位被改变的频次可以知道哪些段是最少使用的,就能对其进行置换。
在这里插入图片描述
如上图,由于段地长度不同,在进行段的换入换出之后,虽然内存中剩余容量足够,但是内存不连续,也导致不能被使用。就如段5无法调入内存。x86有分页技术解决这个问题,将物理内存分为大小相同的页,并将长度不同的段映射到长度相同的页。

02、每个任务独立的虚拟内存

每个任务分配一个虚拟的4GB字节空间:0x00000000~0x7FFFFFFF为私有部分、0x80000000~0xFFFFFFFF为全局部分。
在这里插入图片描述
在多任务系统中,任务的全局部分共有、私有部分独立:
在这里插入图片描述
重新规划任务的内存空间:全局部分和私有部分都是2GB,如下,若私有部分有5个段,分别映射到2GB字节虚拟内存中。
在这里插入图片描述

03、物理内存的分页以及段到页的拆分

任务对应为一些文件,最主要的可执行文件包含代码段、数据段、栈段以及段的实际内容;其他文件可以是工作文档、图像、视频文件等等,可以被加载到数据段中进行处理。
在这里插入图片描述
内核有自己的可执行文件和其他文件,是所有任务共享的;每个任务都有自己独立的可执行文件和其他文件。

当任务执行时,要把可执行文件中的段映射到自己的虚拟内存,映射就是计算每个段在虚拟内存中的起始位置和长度,然后创建和安装其描述符。

映射之后,下一步工作是将段进行切分,然后加载到物理内存。物理内存是4GB字节,每一部分都是一个页,页的最小长度是4KB字节。之后就是将虚拟内存中的段进行4KB字节进行拆分映射到物理内存中。
在这里插入图片描述
如上图,在虚拟内存中的12606字节的段被划分为3个4096字节完整的页 + 1个318字节的页中。即使不足4KB也要按照4KNB字节进行映射。

段是连续的,页不需要是连续的,在内存中空闲的页和被占用的页是随机交错的,无法保证哪些页被释放、哪些页被占用。也就无法保证分配的页在什么位置。
在这里插入图片描述
对内存的分页是逻辑上的、而不是物理上的。同时页的起始位置也有要求,对于4KB字节的页来说,起始位置必须是4096字节即0x1000的整数倍。

课后习题:
在这里插入图片描述

04、处理器的段部件和页部件

分页(Paging:名词,表示以页为基础的内存管理模式),开启分页机制后,在程序执行前,要把可执行文件中的段映射到虚拟内存,然后再把段中的内容加载到物理内存中的页。

为什么要引入虚拟内存、要把程序映射到虚拟内存呢?
Intel处理器是按照段机制工作的,只不过在分页模式下,段是安排在虚拟内存的。将程序映射到虚拟内存就是规划所有段在虚拟内存中的布局和位置。并根据这些信息来创建段描述符
在这里插入图片描述
如上图,处理器只是规划可执行文件在虚拟内存中的布局,并不会把代码加载到虚拟内存中。

在这里插入图片描述
在没有开启分页机制时,段部件输出的地址就是物理地址。
在这里插入图片描述
开启分页机制后,段部件输出的地址就是线性地址,线性地址是虚拟内存中的地址,要传送给页部件,页部件用来将线性地址转换为物理地址。
在这里插入图片描述
页部件段部件送来的线性地址转换为物理地址页部件线性地址拆分成页地址页内偏移,再将页地址修改为真实的页地址即可。如线性地址0x00201000,页部件将页地址转换为0x00004000、偏移为0xCC,则最后转换的物理地址就是0x000040CC

05、从线性地址到物理地址的转换过程

线性地址到物理地址的转换:
在这里插入图片描述
线性地址的前20位对应物理地址的前20位
在这里插入图片描述
在这里插入图片描述
每个表项占4个字节,所以访问表项时,使用虚拟页地址的高20位乘以4。
在这里插入图片描述

  • 段描述符的基地址 + 指令中的偏移量传送给段部件;
  • 段部件输出线性地址0x002010C8
  • 线性地址的高20乘以4去访问表项取出物理页地址的高20位
  • 线性地址的低12位和上一步取出物理页地址的高20位结合形成物理地址;
  • 使用这个物理地址访问内存。

在这里插入图片描述
各个任务都有自己独立的4GB字节虚拟内存空间、和独立的页映射表。

课后作业:
在这里插入图片描述

06、页目录和页表及其地址转换过程

在这里插入图片描述
页表需要4MB字节大小。
在这里插入图片描述
页映射表必须一开始就完全定义,而且会占用4MB字节内存空间。
在这里插入图片描述
层次化的分页结构,即不采用单一的页映射表,使用页目录表页表替代。
页表中每个页表项占据4个字节(32位)用来存放物理页地址,共可保存1024个物理页地址,即每个页表大小为4KB字节。
在这里插入图片描述
CR3存放当前任务页目录的物理地址,也叫做页目录基址寄存器
在这里插入图片描述
没有开启分页机制时,段部件发出的地址就是物理地址0x00801050
开启分页机制:

  • 段部件发出线性地址,处理器将其分为三部分(高10位、中间10位、低12位);
  • 处理器从当前任务状态段TSS中取出CR3寄存器的值,里面存放的是当前任务所用的页目录物理基地址。
  • 接着将线性地址高10乘以4得到页目录中的偏移,从页目录的这个地址中取出页表的物理基地址;
  • 接着将线性地址的中间10位乘以4得到其在页表中的偏移,从页表的这个地址中取出线性地址对应的物理基地址;
  • 接着使用这个基地址 加上 线性地址的低12位形成物理地址,这就把段部件发出的线性地址转换为物理地址了。

其中乘以4是因为页目录和页表中的每一项都是占据4个字节的,那么偏移乘以4才能得到真实的项在对应表中的偏移。

这种变化是事先安排好的,当程序加载时,操作系统先创建虚拟的段,根据段地址的高20位来判断需要用到哪些页目录项和页表项,之后在物理内存中寻找空闲的页,并将页的物理地址填写到对应的页表项中,之后程序就可以按照这些值把线性地址转换为物理地址。

07、设计内核的页目录和页表

本章程序:
引导程序:c13_mbr0.asm
内核程序:c31_core0.asm
用户程序1:c30_app0.asm
用户程序2:c30_app1.asm

在这里插入图片描述
系统中的执行顺序为:

  • 先创建页目录和页表、在虚拟内存中规划每个段的位置并创建段描述符。
  • 处理器的页部件从段部件输出的线性地址中提取前二十位做为索引来访问页目录和页表,看对应的页是否存在。
  • 如果页不存在,则在物理内存中搜索这个页,并将页的物理地址填写在页表中,这样就可以访问这个页。
  • 如果页存在,则直接访问这个页找到对应的物理地址以此访问这个页。

内核程序中,显示处理器品牌信息之后开始准备打开分页机制。但是此时内核是在开启页功能之前加载的,其内容在内存中的位置已经固定。此时要想当前执行流程在开启分页之后还能继续进行,就必须让段部件发出的线性地址 等于 页部件发出的物理地址。
在这里插入图片描述
我们内核处于低端1MB字节,对低端1MB字节的内存特殊处理,让这部分的线性地址 等于 页部件转换之后的物理地址即可。那么这样做之后内核就不需要做任何变动就可以在分页机制下正常工作。
在这里插入图片描述
一个页表可以管理4MB字节内存,那么对于这个内核只需要以一个页表即可。页目录和页表放在任何地址即可,如上,放在0x0002000处。

08、页目录项和页表项的组成格式

目的是将低端1MB字节内存来说,段部件发出的线性地址页部件发出的物理地址相同。

创建页目录,将其清零:

。。。
	;创建系统内核的页目录表PDT
	mov ecx,1024                       	;1024个目录项
	mov ebx,0x00020000                  ;页目录的物理地址
	xor esi,esi							;页目录表清零
.b1:
	mov dword [es:ebx+esi],0x00000000  	;页目录表项清零
	add esi,4
	loop .b1
。。。

页目录项、页表项的组成格式:在页目录中只保存了页表物理地址的高20位、在页表中只保存了页物理地址的高20位。因为页表和页目录要求是4KB字节对其,所以低12位为0。
在这里插入图片描述

  • P位Present):为1时表示页表或页目录存在于内存中、 为0表示不在内存中,需要创建或从磁盘调入。
  • R/W位Read/Write):为0时页目录或页表只读、为1时表示可读可写。
  • US位User/Supervisor):为1时表示所有特权级别的程序访问,为0时表示只有特权级3的程序无法访问。
  • PWTPage Level Write-Through):页级通写位,和高速缓存有关、通写是高速缓存的一种方式,为0表示不允许使用此种方式提升页面访问效率、为1表示允许。
  • PCDPage-Level Cache Disable):高速缓存禁止位,为0表示不适用高速缓存策略、为1表示使用。
  • A位Accessed):由处理器固件设置,为0表示此页未被访问过、为1表示被访问过,操作系统定期将此位清零,通过此位被置1的次数了解此页的使用频率。
  • D位Dirty):由处理器固件设置,用来指示此表项的页已经写过数据。
  • PAT位Page-Attribute Table):页属性表支持位,只对页表项起作用,页目录项中此位置0,和页高速缓存有关。
  • G位Global):指示该表项所指示的页是否为全局性质的,若页是全局的,它将会在高速缓存中一直保存,意味着地址转换的速度会很快,
  • AVL位Available):被处理器忽略,程序可以使用。

09、创建内核的页表并初始化低端1MB对应的页表项

在页目录内创建指向页目录自己的目录项:

。。。
	;将页目录表的物理地址登记在它自己的最后一个页目录项内
	;页目录也可以容纳1024个,从0到3FF,最后一项的偏移为3FF X 4 = 0xFFC = 4092
	mov dword [es:ebx+4092],0x00020003
。。。

在这里插入图片描述
程序前1MB字节占据一个页目录项、和页表的前256个表项。修改页目录项的内容使其指向页表,填写的内容是页表的物理地址:0x00021000,该页位于内中,可读可写,但是不允许特权级别为3的程序访问,所以最终要填写0x00021003

修改页目录种第一个表项的内容,使其指向页表:

。。。
	;在页目录内创建与线性地址0x00000000对应的目录项
	mov d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值