信息安全系统设计基础第十三周学习总结
第九章 虚拟存储器
虚拟存储器是硬件异常,硬件地址翻译,主存,磁盘文件和内核软件的完美交互
虚拟存储器的三个重要能力:
- 将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在主存和磁盘间来回传送数据
- 为每个进程提供了一致的地址空间,从而简化了存储器管理
- 保护了每个进程的地址空间不被其他进程破坏
虚拟机存储器是计算机系统重要概念之一:
- 虚拟机存储器是中心的
- 虚拟机存储器是强大的
- 虚拟机存储器是危险的
第一节 物理和虚拟寻址
每个字节都有唯一的物理地址
物理寻址:CPU访问存储器最自然的方法就是使用物理地址
现代处理机用的是虚拟寻址的形式
第二节 地址空间
地址空间是非负整数的地址集合,如{0,1,2,3……}
若地址空间是连续的,则称其为线性地址空间
现代系统典型地支持32位或者64位的虚拟地址空间
虚拟地址空间:该系统带一个虚拟存储器,CPU从一个有N=2^n个地址的地址空间中生成虚拟地址
物理地址空间:它与系统中物理存储器的M个字节相对应,如{0,1,2,…,M-1}
第三节 虚拟存储器作为缓存的工具
![](http://images2015.cnblogs.com/blog/745408/201512/745408-20151212113629356-94785275.png)
在任意时刻,虚拟页面的集合都分为三个不相交的子集:
- 未分配的:VM系统还未分配(或创建)的页
- 缓存的:当前缓存在物理存储存储器中已分配页
- 未缓存的:没有缓存在物理存储存储器中已分配页
DRAM缓存的组织结构
SRAM缓存来表示位于CPU和主存之间的L1,L2和L3高速缓存,并用DRAM缓存来表示虚拟存储器系统的缓存,它在主存中缓存虚拟页
DRAM缓存的组织完全是由巨大的不命中开销驱动的
由于大的不命中处罚DRAM缓存全是相连的
页表
页命中
缺页
第四节 虚拟存储器作为存储器管理的工具
操作系统为每个进程提供了一个独立的页表
VM简化了链接和加载,代码和数据共享,以及应用程序的存储器分配
- 简化链接:独立的地址空间允许每个进程的存储器映像使用相同的基本格式,而不管代码和数据实际存放在屋里存储器的何处
- 简化加载:虚拟存储器还使得容易向存储器加载可执行文件和共享对象文件
- 简化共享:独立地址空间为操作系统提供了一个管理用户进程和操作系统自身之间共享的一致机制
- 简化存储器分配:虚拟机储存为用户进程提供了一个简单的分配额外存储器机制
第五节 虚拟存储器作为存储器保护机制
若一条指令违反了许可条件,那么CPU就触发一个一般保护故障,将控制传递给一个内核中处理的异常处理程序,Unix外壳一般将这种异常报告为“段错误”
PTE的三个许可位:
- SUP:表示进程是否必须运行在内核模式下才能访问该页
- READ:读权限
- WRITE:写权限
第六节 地址翻译
地址翻译就是一个N元素的虚拟地址空间VAS中的元素和一个M元素的物理地址空间PAS中元素之间的映射
映射:
- 页面基址寄存器PTBR指向当前页表
- MMU利用VPN选择适当的PTE
- PPO=VPO
CPU硬件执行步骤:
当页面命中时,CPU动作:
- 处理器生成虚拟地址,传给MMU
- MMU生成PTE地址,并从高速缓存/主存请求得到他
- 高速缓存/主存向MMU返回PTE
- MMU构造物理地址,并把它传给高速缓存/主存
- 高速缓存/主存返回所请求的数据给处理器。
处理缺页时:
- 处理器生成虚拟地址,传给MMU
- MMU生成PTE地址,并从高速缓存/主存请求得到他
- 高速缓存/主存向MMU返回PTE
- PTE中有效位为0,触发缺页异常
- 确定牺牲页
- 调入新页面,更新PTE
- 返回原来的进程,再次执行导致缺页的指令,会命中
结合高速缓存和虚拟存储器
利用TLB加速地址翻译
多级页表
端对端的地址翻译
第八节 存储器映射
映射对象:
- Unix文件系统中的普通文件
- 匿名文件(全都是二进制0)
再看共享对象
再看fork函数
再看execve函数
加载并运行a.out:
使用mmap函数的用户级存储器映射
参数含义:
- start:这个区域从start开始
- fd:文件描述符
- length:连续的对象片大小
- offset:距文件开始处的偏移量
- prot:访问权限位
参数port: - PROT_EXEC:这个区域内的页面由可以被CPU执行的指令组成
- PROT_READ:这个区域内的页面可读
- PROT_WRITE:这个区域内的页面可写
- PROT_NONE:这个区域内的页面不能被访问
第九节 动态存储器分配
分配器的两种风格:
- 显示分配器-malloc和free
- 隐式分配器/垃圾收集器
malloc和free函数
malloc函数:
sbrk函数:
free函数:
分配器的要求和目标:
要求:
- 处理任意请求序列
- 立即响应请求
- 只使用堆
- 对齐块
- 不修改已分配的块
目标: - 最大化吞吐率(吞吐率:每个单位时间里完成的请求数)
- 最大化存储器利用率——峰值利用率最大化
碎片
- 外部碎片
- 内部碎片
现实问题
- 空闲块组织
- 放置
- 分割
- 合并
隐式空闲链表
将堆组织成一个连续的已分配块和空闲块的序列:
放置已分配的块
放置策略:
- 首次适配:从头开始搜索空闲链表,选择第一个合适的空闲块
- 下一次适配:从上一次搜索的结束位置开始搜索
- 最佳适配:检索每个空闲块,选择适合所需请求大小的最小空闲块
获取额外的堆储存器
合并空闲块
带边界标记的合并
第十节 垃圾收集
垃圾收集器是一种动态存储分配器,它自动释放程序不再需要的已分配块,这些块被称为垃圾,自动回收堆存储的过程叫做垃圾收集
垃圾收集器将存储器视作一张有向可达图,只有当存在一条从任意根节点出发并到达p的有向路径时,才说节点p是可达的,而不可达点就是垃圾
Mark&Sweep垃圾收集器
- ptr isPtr(ptr p):如果p指向一个已分配块中的某个字,那么就返回一个指向这个块的起始位置的指针b,否则返回NULL
- int blockMarked(ptr b):如果已经标记了块b,那么就返回true
- int blockAllocated(ptr b):如果块b是已分配的,那么久返回ture
- void markBlock(ptr b):标记块b
- int length(ptr b):返回块b的以字为单位的长度,不包括头部
- void unmarkBlock(ptr b):将块b的状态由已标记的改为未标记的
- ptr nextBlock(ptr b):返回堆中块b的后继
C程序的保守Mark&Sweep
第十一节 C程序中常见的与存储器有关的错误
间接引用坏指针
scanf错误
读未初始化的存储器
假设堆存储器被初始化为0
允许栈缓冲区溢出
缓冲区溢出错误
假设指针和它们指向的对象是相同大小的
在远处起作用action at distance