2017-2018-1 20155227 《信息安全系统设计基础》第十一周学习总结
2017-2018-1 20155227 《信息安全系统设计基础》第十一周学习总结
教材学习内容总结
第九章 虚拟内存
虚拟存储器
虚拟存储器是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的完美交互,它为每个进程提供了一个大的、一致的和私有的地址空间。通过一个很清晰的机制,虚拟存储器提供了三个重要的能力:
(1)它将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,它高效地使用了主存。
(2)它为每个进程提供了一致的地址空间,从而简化了存储器管理。
(3)它保护了每个进程的地址空间不被其他进程破坏。
物理和虚拟寻址
物理寻址:
计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组。每字节都有一个唯一的物理地址(Physical Address,PA)。第一个字节的地址为0,接下来的字节的地址为1,再下一个为2,依此类推。给定这种简单的结构,CPU访问存储器的最自然的方式就是使用物理地址,我们把这种方式称为物理寻址。
虚拟寻址:
使用虚拟寻址时,CPU通过生成一个虚拟地址(Virtual Address,VA)来访问主存,这个虚拟地址在被送到存储器之前先转换成适当的物理地址。将一个虚拟地址转换为物理地址的任务叫做地址翻译(address translation)。就像异常处理一样,地址翻译需要CPU硬件和操作系统之间的紧密合作。CPU芯片上叫做存储器管理单元(Memory Management Unit,MMU)的专用硬件,利用存放在主存中的查询表来动态翻译虚拟地址,该表的内容是由操作系统管理。
地址空间
地址空间时一个非负整数地址的有序集合,如果地址空间中的整数是连续的,那么我们说它是一个线性地址空间。CPU从一个有N=2n
个地址空间中生成虚拟地址,这个地址空间称为虚拟地址空间。一个地址空间的大小事由表示最大地址所需要的位数来描述的。一个包含N=2n
个地址的虚拟地址空间就叫做一个n位地址空间。一个系统还有一个物理地址空间,它与系统中物理存储器的字节数目相对应。主存中的每个字节都有一个选自虚拟地址空间的虚拟地址和一个选自物理地址空间的物理地。
虚拟存储器作为缓存的工具
概念上而言,虚拟存储器(VM)被组织为一个由存放在磁盘上N个连续的字节大小的单元组成的数组。每个字节都有一个唯一的虚拟地址,这个唯一的虚拟地址是作为到数组的索引的。磁盘上的数组的内容被缓存在主存中。和存储器层次结构中其他缓存一样,磁盘(较低层)上的数据被分割成块,这些块作为磁盘和主存(较高层)之间的传输单元。VM系统通过将虚拟存储器分割称为虚拟页(Vitual Page,VP)的大小固定的块来处理这个问题。每个虚拟页的大小为P = 2 ^ n
字节。类似地,物理存储器被分割为物理页(Physical Page,PP),大小也为P字节(物理页也称为页帧(page frame))。
在任意时刻,虚拟页面的集合都分为三个不相交的子集:
未分配的:VM系统还未分配(或者创建)的页。未分配的块没有任何数据和它们相关联,因此也就不占用任何磁盘空间。(没有调用malloc或者mmap的)
缓存的:当前缓存在物理存储中的已分配页。(已经调用malloc和mmap的,在程序中正在引用的)
未缓存的:没有缓存在物理存储器中的已分配页。(已经调用malloc和mmap的,在程序中还没有被引用的)
页表
地址翻译
页面命中,CPU硬件执行的步骤:
处理器生成一个虚拟地址,并把它传送给MMU
MMU生成PTE地址,并从高速缓存/主存请求得到它
高速缓存/主存向MMU返回PTE
MMU构造物理地址,并把它传送给高速缓存/主存
高速缓存/主存返回所请求的数据字给处理器
页面命中完全是由硬件来处理的,与之不同的是,处理缺页要求硬件和操作系统内核协作完成:
前三步都是一样的
PTE中的有效位为0,所以MMU触发了一次异常,传递CPU中的控制到操系统内核中的缺页异常处理程序。
缺页处理程序确定出物理存储器中的牺牲页,如果这个页面被修改了,则把它换出到磁盘。
缺页处理程序页面调入新的页面,并更新存储器中的PTE
缺页处理程序返回到原来的进程,再次执行导致缺页的指令。CPU将引起缺页的虚拟地址重新发送给MMU
页面没有命中:
虚拟页偏移量(VPO)和物理页偏移量(PPO)大小是相等的,因为虚拟页偏移量就是虚拟页的大小,对于给定的虚拟地址位数和物理地址位数就可以构造各个量的大小。比如32位虚拟地址空间和24为物理地址,对于大小为1KB的页面。那么VPO和PPO的大小为10位,22位的虚拟页号,物理页号为12位。
但是在现在的系统中,都是结合高速缓存和虚拟存储器一起使用的,大多数系统都是选择物理地址来访问高速缓存。
多级页表
一级页表的每个PTE负责映射虚拟地址空间中一个4MB的片,这里每一片都是由1024个连续的页面组成的。假设地址空间为4GB,1024个PTE已经足够覆盖整个空间了。
如果偏i中的每个页面都未被分配,那么一级PTEi就为空,上图中的片2~7是未被分配的。如果在片i中至少有一个页是分配了的,那么一级PTEi就指向一个二级页表的基址。上图中的片0、1、8的所有或则部分已被分配,所以他们的一级PTE就指向二级页表。
二级页表中的每个PTE都负责映射一个4KB的虚拟存储器页面,就像我们查看一级页表一样。注意,使用4字节的PTE,每个一级和二级页表都是4KB字节,这刚好和一个页面的大小一样的(为啥呢?4字节的PTE,一个页表有1024个页表项,所以一个页表就是4KB)。
如果一级页表中的一个PTE是空的,那么相应的二级页表就根本不会存在,这代表这一种巨大的潜在节约;只有一级页表才需要总是存在主存中;虚拟存储器系统可以在需要时创建、页面调入或调出二级页表,这就减少了主存的压力;只有最经常使用的二级页表才需要缓存在主存中。
存储器映射
linux虚拟存储器系统的存储映射问题:
linux为每个进程维护一个单独的虚拟地址空间。
虚拟存储器是对主存的一个抽象。支持虚拟存储器的处理器通过使用一种叫做虚拟寻址的间接形式来引用主存。处理器产生一个虚拟地址,在被发送到主存之前,这个地址被翻译成一个物理地址。从虚拟地址空间到物理地址翻译要求硬件和软件紧密合作。专门的硬件通过使用页表来翻译虚拟地址,页表的内容是由操作系统提供的。
再看共享对象
共享对象的由来:
许多进程有同样的只读文本区域。
printf
运行Uinx shell的tcsh
如果每个进程都加载进内存一次,极其浪费。
存储器映射提供一种机制,来共享对象。
一个对象被映射到虚拟存储器的一个区域,一定属于以下两种。
- 共有对象
一个进程将一个共有对象映射到它的虚拟地址空间的一个区域。
进程对这个区域的写操作,对于那些也把这个共享对象映射它的虚拟存储器的进程是可见的。
这些变化也会反映到磁盘上的原始对象。
映射到的虚拟存储器那个区域叫做共享区域。
- 私有对象
对一个映射到私有对象的区域做出的改变,对于其他进程不可见.
并且进行的写操作不会反映到磁盘上。
映射到的虚拟存储器那个区域叫做私有区域。
再看fork函数
- 当fork函数被当前进程调用时。
内核为新进程创建内核数据结构,并分配给它唯一一个PID。
为了给新进程创建虚拟存储器。
创建了当前进程的mm_struct,区域结构和页表的原样拷贝。
将两个进程的每个页面都标记为只读。并给两个区域进程的每个区域结构都标记为私有的写时拷贝。
- 当fork函数在新进程返回时。
新进程现在的虚拟存储器刚好和调用fork时存在的虚拟存储器相同。
当两个进程中任一个需要被写时,触发写时拷贝机制。
教材学习中的问题和解决过程
-
问题1:为什么要使用动态存储器分配?
-
问题1解决:
程序使用动态存储器分配的最重要原因是经常直到程序实际运行时,它们才知道某些数据结构的大小。所以需要使用动态存储器分配。
-
问题2: 在使用C语言和虚拟存储器打交道时,很容易犯缓冲区溢出错误,应该怎么避免这个问题?
-
问题2解决:
不检查串的大小就写入栈中的目标缓冲区可能会有缓冲区溢出错误。
代码调试中的问题和解决过程
无
代码托管
(statistics.sh脚本的运行结果截图)
上周考试错题总结
无
结对及互评
点评模板:
- 博客中值得学习的或问题:
- xxx
- xxx
- ...
- 代码中值得学习的或问题:
- xxx
- xxx
- ...
- 其他
本周结对学习情况
-[20155318](http://www.cnblogs.com/lxy1997/)
- 结对照片
- 结对学习内容
- 教材第九章内容
- 一起完成实验四
- ...
其他(感悟、思考等,可选)
通过这一章的学习,加深了对虚拟存储器的具体功能的了解。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 133/133 | 1/1 | 8/8 | |
第三周 | 159/292 | 1/3 | 10/18 | |
第五周 | 121/413 | 1/5 | 10/28 | |
第七周 | 835/3005 | 2/7 | 10/38 | |
第八周 | 1702/4777 | 1/8 | 10/48 | |
第九周 | 1664/6441 | 3/11 | 10/58 | |
第十一周 | 300/6741 | 3/14 | 10/68 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
-
计划学习时间:15小时
-
实际学习时间:10小时
-
改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)