20145222《信息安全系统设计基础》第十四周学习总结
教材学习内容总结
- 虚拟存储器3个重要的能力:
(1)将主存看作是一个存储在磁盘上的地址空间的高速缓存,在主存中只保护活动的区域,并根据需要在磁盘和主存之间来回传送数据;
(2)为每个进程提供了一致的地址空间,从而简化了存储器管理;
(3)保护了每个进程的地址空间不被其它进程破坏。
- 程序员需要理解虚拟存储器的原因:
(1)虚拟存储器是中心的:它是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的交互中心; (2)虚拟存储器是强大的:它可以创建和销毁存储器片、可以映射存储器片映射到磁盘某个部分等等;
(3)虚拟存储器若操作不当则十分危险。
9.1 物理和虚拟寻址
1、物理地址PA:计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组,每字节都有一个唯一的物理地址PA。根据物理地址寻址的是物理寻址。
2、地址翻译:使用虚拟寻址时,CPU通过生成一个虚拟地址VA来访问主存,这个虚拟地址在被送到存储器之前先转换成适当的物理地址,相关硬件为存储器管理单元MMU。
9.2 地址空间
1、线性地址空间:地址空间中的整数是连续的。
2、虚拟地址空间:CPU从一个有 N=2^n 个地址的地址空间中生成虚拟地址,这个地址空间成为称为虚拟地址空间。
3、地址空间的大小:由表示最大地址所需要的位数来描述。
4、物理地址空间:与系统中的物理存储器的M个字节相对应。
5、虚拟存储器的基本思想:主存中的每个字节都有一个选自虚拟地址空间的虚拟地址和一个选自物理地址空间的物理地址。
9.3 虚拟存储器作为缓存的工具
- 任意时刻,虚拟页面的集合都被分为三个不相交的子集:
未分配的:VM系统还没分配/创建的页,不占用任何磁盘空间。
缓存的:当前缓存在物理存储器中的已分配页
未缓存的:没有缓存在物理存储器中的已分配页
-
虚拟存储器——虚拟页VP,每个虚拟页大小为P=2^平字节
物理存储器——物理页PP,也叫页帧,大小也为P字节。 -
页表:是一个数据结构,存放在物理存储器中,将虚拟页映射到物理页,就是一个页表条目的数组。
页表就是一个页表条目PTE的数组。 -
PTE:由一个有效位和一个n位地址字段组成的,表明了该虚拟页是否被缓存在DRAM中。 页表的组成:有效位+n位地址字段
-
如果设置了有效位:
地址字段表示DRAM中相应的物理页的起始位置,这个物理页中缓存了该虚拟页。
如果没有设置有效位:
空地址:表示该虚拟页未被分配
不是空地址:这个地址指向该虚拟页在磁盘上的起始位置。
-
当CPU读取一个字的时候,地址翻译硬件将虚拟地址作为一个索引来定位PTE,并从存储器中读取它。
-
DRA缓存不命中称为缺页。在不命中发生时,换入页面的策略称为按需页面调度。
-
颠簸:工作集大小超出了物理存储器的大小。
9.4 虚拟存储器作为存储器管理工具
按需页面调度和独立的虚拟地址空间的结合简化了链接和加载、代码和数据共享,以及应用程序的存储器分配。
简化链接:独立的地址空间允许每个进程的存储器映像使用相同的基本格式,而不管代码和数据实际存放在物理存储器的何处。
简化加载:虚拟存储器使得容易想存储器中加载可执行文件和共享文件对象。
简化共享:独立地址空间为操作系统提供了一个管理用户进程和操作系统自身之间共享的一致机制。
简化存储器分配:虚拟存储器为向用户进程提供一个简单的分配额外存储器的机制。
9.5 虚拟存储器作为存储器保护的工具
PTE的三个许可位:
SUP:表示进程是否必须运行在内核模式下才能访问该页
READ:读权限
WRITE:写权限
9.6 地址翻译
-
地址翻译:一个N元素的虚拟地址空间(VAS)中的元素和一个M元素的物理地址空间(PAS)之间的映射。
-
MAP:VAS→PAS∪空 MAP(A)=
A':如果虚拟地址A处的数据在PAS的物理地址A处' 空:如果虚拟地址A处的数据不在物理存储器中
-
CPU中的一个控制寄存器页表基址寄存器指向当前页表,n位的虚拟地址包含两个部分:一个p位的虚拟页面偏移(VPO) 和一个(n-p)位的虚拟页号,页表条目中的物理页页号和虚拟地址中的VPO串联起来,就得到了相应的物理地址。
-
主要思路:地址翻译发生在高速缓存之前,页表目录可以缓存,就像其他的数据字一样。
-
TLB:翻译后备缓冲器,是一个小的、虚拟存储的缓存,其中每一行都保存着一个由单个PTE组成的块。
-
多级页表——采用层次结构,用来压缩页表。 2、以两层页表层次结构为例,好处是:
如果一级页表中的一个PTE是空的,那么相应的二级页表就根本不会存在
只有一级页表才需要总是在主存中,虚拟存储器系统可以在需要时创建、页面调入或调出二级页表,只有最经常使用的二级页表才缓存在主存中。
9.7 案例研究
-
PTE的三个权限位:
R/W位:确定内容是读写还是只读 U/S位:确定是否能在用户模式访问该页 XD位:禁止执行位,64位系统中引入,可以用来禁止从某些存储器页取指令
-
缺页处理程序涉及到的位:
A位,引用位,实现页替换算法 D位,脏位,告诉是否必须写回牺牲页
-
linux为每个进程维持了一个单独的虚拟地址空间,其中,内核虚拟存储器位于用户栈之上;
内核虚拟存储器包含内核中的代码和数据结构,还有一些被映射到一组连续的物理页面(主要是便捷地访问特定位置,比如执行I/O操作的时候需要的位置) -
linux将虚拟存储器组织成一些区域(也叫做段)的集合。一个区域就是已经存在的(已分配的)虚拟存储器的连续片;
允许虚拟地址空间有间隙;内核不用记录那些不存在的页,这样的页也不用占用存储器;
区域结构:
vm _start:指向这个区域的起始处;
vm _end:指向这个区域的结束处;
vm _prot:描述这个区域内所包含的所有页的读写许可权限;
vm _fags:描述这个区域内的页面是与其他进程共享的,还是这个进程私有的,等等;
vm _next:指向链表的下一个结构.
3、linux缺页异常处理
9.8 存储器映射
-
存储器映射:Linux通过将一个虚拟存储器区域与一个磁盘上的对象关联起来,以初始化这个虚拟存储器区域的内容的过程。
-
映射对象:
Unix文件系统中的普通文件
匿名文件:全都是二进制0 -
一旦一个虚拟页面被初始化了,它就在一个由内核维护的专门的交换文件之间换来换去。交换文件也叫交换空间,或交换区域。
-
共享对象对于所有把它映射到自己的虚拟存储器进程来说都是可见的。
即使映射到多个共享区域,物理存储器中也只需要存放共享对象的一个拷贝。 -
私有对象运用的技术:写时拷贝
在物理存储器中只保存有私有对象的一份拷贝 -
fork函数
1、当fork函数被当前进程调用时,内核为新进程创建各种数据结构,并分配给它一个唯一的PID。为了给这个新进程创建虚拟存储器,它创建了当前进程的mm_struct、区域结构和页表的原样拷贝。它将两个进程中的每个页面都为标记只读,并将两个进程中的每个区域结构都标记为私有的写时拷贝。
2、当fork在新进程中返回时,新进程现在的虚拟存储器刚好和调用fork时存在的虚拟存储器相同。当这两个进程中的任一个后来进行写操作时,写时拷贝机制就会创建新页面,因此,也就为每个进程保持了私有地址空间的抽象概念。 -
使用execve函数将a.out程序加载到存储器的过程
Execve("a.out",NULL,NULL);
-
加载并运行所需要的步骤如下:
(1)删除已存在的用户区域。 (2)映射私有区域。 (3)映射共享区域。 (4)设置程序计数器。
-
Unix进程可以使用mmap函数来创建新的虚拟存储器区域,并将对象映射到这些区域当中
void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offest);
若成功则为指向映射区域的指针,若出错则为MAP_FAILDE(-1) -
munmap函数删除虚拟存储器的区域。
int munmap(void *start,size_t length);
若成功则返回0,若失败则返回-1.
9.9 动态存储器分配
-
当运行时需要额外虚拟存储器时,使用动态存储器分配器维护一个进程的虚拟存储器区域。
-
分配器有两种风格。
显示分配器:要求应用显式地释放任何已经分配的块。 隐式分配器:要求分配器检测一个已分配块何时不再被程序所使用,就释放这个块。也叫做垃圾收集器。
-
系统调用malloc函数,从堆中分配块:
#include <stdlib.h> void *malloc(size_t size); 成功返回指针,指向大小至少为size字节的存储器块,失败返回NULL
-
系统调用free函数来释放已分配的堆块:
#include <stdlib.h> void free(void *ptr); 无返回值,ptr参数必须指向一个从malloc、calloc或者reallov获得的已分配块的起始位置。
-
使用动态存储器分配原因:经常直到程序实际运行时,才知道某些数据结构的大小。
-
显示分配器的要求:
(1)处理任意请求序列 (2)立即响应请求 (3)只使用堆 (4)对齐块 (5)不修改已分配的块
-
目标:
(1)最大化吞吐率:最大化存储器利用率——峰值利用率最大化 (2)吞吐率:每个单位时间里完成的请求数
-
碎片:虽然有未使用的存储器,但是不能用来满足分配请求。
内部碎片:发生在一个已分配块比有效载荷大的时候,易于量化。 外部碎片:发生在当空闲存储器合计起来足够满足一个分配请求,但是没有一个单独的空间块足以处理这个请求时发生。难以量化,不可预测。
-
堆块的格式:由一个字的头部,有效荷载,和可能的额外填充组成。
-
将堆组织成一个连续的已分配块和空闲块的序列:
空闲块通过头部中的大小字段隐含地连接着,分配器可以通过遍历堆中所有的块,从而间接地遍历整个空闲块的集合。
3、需要:特殊标记的结束块。 4、系统对齐要求和分配器对块格式的选择会对分配器上的最小块大小有强制的要求。
-
放置已分配的块,分配方式有:
(1)首次适配:从头开始搜索空闲链表,选择第一个合适的空闲块 (2)下一次适配:从上一次搜索的结束位置开始搜索 (3)最佳适配:检索每个空闲块,选择适合所需请求大小的最小空闲块
代码托管链接
这周没有敲代码。。。。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 4000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 2/3 | 10/20 | 掌握了几个命令 |
第二周 | 0/0 | 1/4 | 8/28 | 熟练了vim编辑器的操作 |
第三周 | 40/40 | 1/5 | 12/40 | 开始敲代码了 |
第五周 | 36/76 | 2/7 | 15/55 | 慢慢熟悉了汇编语言 |
第六周 | 12/88 | 2/9 | 16/71 | 对机器语言指令有了更深一步的理解 |
第七周 | 50/138 | 3/12 | 30/101 | 多写实用性强的博客,慢慢养成好习惯 |
第九周 | 200/338 | 2/15 | 25/126 | 理解了系统级I/O的一些基本原理 |
第十周 | 350/688 | 2/17 | 30/156 | 懂得了一些命令的具体代码原理 |
第十一周 | 450/1138 | 2/19 | 30/186 | 学习要下功夫才有趣 |
第十二周 | 50/1188 | 4/23 | 20/206 | 实践操作会增加学习兴趣 |
第十三周 | 355/1543 | 2/25 | 20/226 | 着重理解了并发线程的工作原理 |
第十四周 | 0/1543 | 2/27 | 15/241 | 了解了虚拟存储器的概念 |