20145317《信息安全系统设计基础》第十四周学习总结

20145317《信息安全系统设计基础》第十四周学习总结

教材学习内容总结

  • 虚拟存储器的三个重要能力:

    • 它将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,高效的使用了主存。
    • 它为每个进程提供了一致的地址空间,从而简化了存储器管理。
    • 它保护了每个进程的地址空间不被其他进程破坏。
  • 程序员需要理解虚拟存储器的三个原因:
    • 虚拟存储器是中心的:它是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的交互中心;
    • 虚拟存储器是强大的:它可以创建和销毁存储器片、可以映射存储器片映射到磁盘某个部分等等;
    • 虚拟存储器若操作不当则十分危险。

物理和虚拟寻址

  • 计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组,每字节都有一个唯一的物理地址(PA)。CPU根据物理地址访问存储器的方式是物理寻址。
  • 使用虚拟寻址时,CPU通过生成一个虚拟地址VA来访问主存,这个虚拟地址在被送到存储器之前先转换成适当的物理地址,地址翻译通过CPU芯片上的存储器管理单元完成。

地址空间

  • 地址空间是一个非负整数地址的有序集合:{0,1,2,……}

    • 线性地址空间:地址空间中的整数是连续的。
    • 虚拟地址空间:CPU从一个有 N=2^n 个地址的地址空间中生成虚拟地址,这个地址空间成为称为虚拟地址空间。
    • 地址空间的大小:由表示最大地址所需要的位数来描述。
    • 物理地址空间:与系统中的物理存储器的M个字节相对应。
  • 虚拟存储器的基本思想:主存中的每个字节都有一个选自虚拟地址空间的虚拟地址和一个选自物理地址空间的物理地址。

虚拟存储器作为缓存的工具

  • 虚拟存储器——虚拟页(VP),每个虚拟页大小为P=2^p字节。
  • 物理存储器——物理页(PP),也叫页帧,大小也为P字节。
  • 任意时刻,虚拟页面的集合都被分为三个不相交的子集:
    • 未分配的:VM系统还没分配(创建)的页,不占用任何磁盘空间。
    • 缓存的:当前缓存在物理存储器中的已分配页。
    • 未缓存的:没有缓存在物理存储器中的已分配页。

DRAM缓存的组织结构

  • 不命中处罚很大
  • 是全相联的——任何虚拟页都可以放在任何的物理页中
  • 替换算法精密
  • 总是使用写回而不是直写

页表

  • 页表:是一个数据结构,存放在物理存储器中,将虚拟页映射到物理页,就是一个页表条目的数组。
  • 页表就是一个页表条目PTE的数组。
    • PTE:由一个有效位和一个n位地址字段组成的,表明了该虚拟页是否被缓存在DRAM中。
  • 页表的组成:有效位+n位地址字段
  • 如果设置了有效位:地址字段表示DRAM中相应的物理页的起始位置,这个物理页中缓存了该虚拟页。
  • 如果没有设置有效位:
    • 空地址:表示该虚拟页未被分配
    • 不是空地址:这个地址指向该虚拟页在磁盘上的起始位置。

页命中

  • 当CPU读取一个字的时候,地址翻译硬件将虚拟地址作为一个索引来定位PTE,并从存储器中读取它。

缺页

  • 缺页:就是指DRAM缓存不命中。
  • 缺页异常:会调用内核中的缺页异常处理程序,选择一个牺牲页。
  • 页:虚拟存储器的习惯说法,就是块
  • 交换=页面调度:磁盘和存储器之间传送页的活动
  • 按需页面调度:直到发生不命中时才换入页面的策略,所有现代系统都使用这个。

又是局部性救了我们

  • 局部性原则保证了在任意时刻,程序将往往在一个较小的活动页面集合上工作,这个集合叫做工作集/常驻集。
  • 所以只要程序有良好的时间局部性,虚拟存储器系统就能工作的相当好。
  • 颠簸:工作集大小超出了物理存储器的大小。

虚拟存储器作为存储器管理的工具

  • 操作系统为每个进程提供了一个独立的页表,也就是一个独立的虚拟地址空间。
  • 多个虚拟页面可以映射到同一个共享物理页面上。
  • 存储器映射:将一组连续的虚拟页映射到任意一个文件中的任意位置的表示法。
  • 按需页面调度和独立的虚拟地址空间的结合简化了链接和加载、代码和数据共享,以及应用程序的存储器分配。
    • 简化链接:独立的地址空间允许每个进程的存储器映像使用相同的基本格式,而不管代码和数据实际存放在物理存储器的何处。
    • 简化加载:虚拟存储器使得容易想存储器中加载可执行文件和共享文件对象。
    • 简化共享:独立地址空间为操作系统提供了一个管理用户进程和操作系统自身之间共享的一致机制。
    • 简化存储器分配:虚拟存储器为向用户进程提供一个简单的分配额外存储器的机制。

虚拟存储器作为存储器保护的工具

  • 通过在PTE上添加一些额外的许可来控制对一个虚拟页面的内容访问。
  • PTE的三个许可位:
    • SUP:表示进程是否必须运行在内核模式下才能访问该页
    • READ:读权限
    • WRITE:写权限

地址翻译

  • 地址翻译:一个N元素的虚拟地址空间(VAS)中的元素和一个M元素的物理地址空间(PAS)之间的映射。
  • MAP: VAS → PAS ∪ ?
    • MAP = A‘ ,如果虚拟地址A处的数据在PAS的物理地址A‘处
    • MAP = ? ,如果虚拟地址A处的数据不在物理存储器中
  • CPU中的一个控制寄存器页表基址寄存器指向当前页表,n位的虚拟地址包含两个部分:一个p位的虚拟页面偏移(VPO) 和一个(n-p)位的虚拟页号,页表条目中的物理页页号和虚拟地址中的VPO串联起来,就得到了相应的物理地址。
  • 当页面命中时,CPU硬件执行步骤
    • 处理器生成虚拟地址,传给MMU
    • MMU生成PTE地址,并从高速缓存/主存请求得到他
    • 高速缓存/主存向MMU返回PTE
    • MMU构造物理地址,并把它传给高速缓存/主存
    • 高速缓存/主存返回所请求的数据给处理器。
  • 处理缺页时,CPU硬件执行步骤
    • 处理器生成虚拟地址,传给MMU
    • MMU生成PTE地址,并从高速缓存/主存请求得到他
    • 高速缓存/主存向MMU返回PTE
    • PTE中有效位为0,触发缺页异常
    • 确定牺牲页
    • 调入新页面,更新PTE
    • 返回原来的进程,再次执行导致缺页的指令,会命中

结合高速缓存和虚拟存储器

  • 在既使用SRAM高速缓存又使用虚拟存储器的系统中,大多数系统选择物理寻址。
  • 两者结合的主要思路是地址翻译发生在高速缓存之前。
  • 页表目录可以缓存,就像其他的数据字一样。

利用TLB加速地址翻译

  • TLB:翻译后备缓冲器,是一个小的、虚拟存储的缓存,其中每一行都保存着一个由单个PTE组成的块
  • 步骤:
    • CPU产生一个虚拟地址
    • MMU从TLB中取出相应的PTE
    • MMU将这个虚拟地址翻译成一个物理地址,并且将它发送到高速缓存/主存
    • 高速缓存/主存将所请求的数据字返回给CPU

多级页表

  • 多级页表——采用层次结构,用来压缩页表。
  • 以两层页表层次结构为例,好处是:
    • 如果一级页表中的一个PTE是空的,那么相应的二级页表就根本不会存在;
    • 只有一级页表才需要总是在主存中,虚拟存储器系统可以在需要时创建、页面调入或调出二级页表,只有最经常使用的二级页表才缓存在主存中。

案例研究:Intel Core i7/Linux存储器系统

core i7地址翻译

  • PTE的三个权限位:

    • R/W位:确定内容是读写还是只读
    • U/S位:确定是否能在用户模式访问该页
    • XD位:禁止执行位,64位系统中引入,可以用来禁止从某些存储器页取指令
  • 缺页处理程序涉及到的位:
    • A位:引用位,实现页替换算法
    • D位:脏位,告诉是否必须写回牺牲页

Linux虚拟存储器系统

  • linux为每个进程维持了一个单独的虚拟地址空间,其中,内核虚拟存储器位于用户栈之上;
  • 内核虚拟存储器包含内核中的代码和数据结构,还有一些被映射到一组连续的物理页面(主要是便捷地访问特定位置,比如执行I/O操作的时候需要的位置)
  • linux将虚拟存储器组织成一些区域(也叫做段)的集合。一个区域就是已经存在的(已分配的)虚拟存储器的连续片;
  • 允许虚拟地址空间有间隙;内核不用记录那些不存在的页,这样的页也不用占用存储器;
  • 一个具体区域的区域结构:
    • vm _start:指向这个区域的起始处;
    • vm _end:指向这个区域的结束处;
    • vm _prot:描述这个区域内所包含的所有页的读写许可权限;
    • vm _fags:描述这个区域内的页面是与其他进程共享的,还是这个进程私有的,等等;
    • vm _next:指向链表的下一个结构。

存储器映射

  • 存储器映射:Linux通过将一个虚拟存储器区域与一个磁盘上的对象关联起来,以初始化这个虚拟存储器区域的内容的过程。
  • 映射对象:
    • Unix文件系统中的普通文件
    • 匿名文件(全都是二进制0)
  • 一旦一个虚拟页面被初始化了,它就在一个由内核维护的专门的交换文件之间换来换去。交换文件也叫交换空间,或交换区域。

再看共享对象

  • 共享对象

    • 共享对象对于所有把它映射到自己的虚拟存储器进程来说都是可见的。
    • 即使映射到多个共享区域,物理存储器中也只需要存放共享对象的一个拷贝。
  • 私有对象
    • 私有对象运用的技术:写时拷贝
    • 在物理存储器中只保存有私有对象的一份拷贝

再看fork函数

  • 当fork函数被当前进程调用时,内核为新进程创建各种数据结构,并分配给它一个唯一的PID。为了给这个新进程创建虚拟存储器,它创建了当前进程的mm_struct、区域结构和页表的原样拷贝。它将两个进程中的每个页面都为标记只读,并将两个进程中的每个区域结构都标记为私有的写时拷贝。
  • 当fork在新进程中返回时,新进程现在的虚拟存储器刚好和调用fork时存在的虚拟存储器相同。当这两个进程中的任一个后来进行写操作时,写时拷贝机制就会创建新页面,因此,也就为每个进程保持了私有地址空间的抽象概念。

再看execve函数

  • 使用execve函数将a.out程序加载到存储器的过程

    Execve("a.out",NULL,NULL);
  • 加载并运行所需要的步骤如下:
    • 删除已存在的用户区域。
    • 映射私有区域。
    • 映射共享区域。
    • 设置程序计数器。

使用mmap函数的用户级存储器映射

  • 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.

动态存储器分配

  • 当运行时需要额外虚拟存储器时,使用动态存储器分配器维护一个进程的虚拟存储器区域。
  • 分配器有两种风格:
    • 显示分配器:要求应用显式地释放任何已经分配的块。
    • 隐式分配器:要求分配器检测一个已分配块何时不再被程序所使用,就释放这个块。也叫做垃圾收集器。

malloc和free函数

  • 系统调用malloc函数,从堆中分配块:
#include <stdlib.h>
void *malloc(size_t size);
成功返回指针,指向大小至少为size字节的存储器块,失败返回NULL
  • 系统调用free函数来释放已分配的堆块:
#include <stdlib.h>
void free(void *ptr);

无返回值
ptr参数必须指向一个从malloc、calloc或者reallov获得的已分配块的起始位置。
  • 使用动态存储器分配原因:经常直到程序实际运行时,才知道某些数据结构的大小。

分配器的要求和目标

  • 显示分配器的要求:

    • 处理任意请求序列
    • 立即响应请求
    • 只使用堆
    • 对齐块
    • 不修改已分配的块
  • 目标:
    • 最大化吞吐率:最大化存储器利用率——峰值利用率最大化
    • 吞吐率:每个单位时间里完成的请求数

碎片

  • 碎片:虽然有未使用的存储器,但是不能用来满足分配请求。

    • 内部碎片:发生在一个已分配块比有效载荷大的时候,易于量化。
    • 外部碎片:发生在当空闲存储器合计起来足够满足一个分配请求,但是没有一个单独的空间块足以处理这个请求时发生。难以量化,不可预测。

隐式空闲链表

  • 堆块的格式:由一个字的头部,有效荷载,和可能的额外填充组成。
  • 将堆组织成一个连续的已分配块和空闲块的序列:
    • 空闲块通过头部中的大小字段隐含地连接着,分配器可以通过遍历堆中所有的块,从而间接地遍历整个空闲块的集合。
  • 需要:特殊标记的结束块。
  • 系统对齐要求和分配器对块格式的选择会对分配器上的最小块大小有强制的要求。

放置已分配的块

  • 分配方式有:

    • 首次适配:从头开始搜索空闲链表,选择第一个合适的空闲块
    • 下一次适配:从上一次搜索的结束位置开始搜索
    • 最佳适配:检索每个空闲块,选择适合所需请求大小的最小空闲块

申请额外的堆存储器

  • sbrk函数
#include <unistd.h>
vid *sbrk(intptr_t incr);

成功则返回旧的brk指针,出错为-1
  • 通过将内核的brk指针增加incr来扩展和收缩堆。

    合并空闲块

  • 合并是针对于假碎片问题的,任何实际的分配器都必须合并相邻的空闲块。
  • 两种策略:
    • 立即合并
    • 推迟合并

垃圾收集

  • 垃圾收集器是一种动态存储分配器。,自动释放程序已经不再需要的已分配块(垃圾)。

基本知识

  • 垃圾收集器将存储器视为一张有向可达图,图的节点被分配为一组根节点和一组堆节点。当存在一条从任意根节点出发到并到达P的有向路径时,就称节点P是可达的。

Mark&Sweep垃圾收集器

  • Mark&Sweep垃圾收集器由标记阶段和清除阶段组成,标记阶段标记出根节点所有可达的和已分配的后继,清除阶段释放每个未被标记的已分配块。
  • 在对Mark&Sweep的描述中使用下列函数:
    • ptr isPtr(ptr p):如果p指向一个已分配块中的某个字,那么就返回一个指向这个块起始位置的指针b,否则返回NULL。
    • int blockMarked(ptr b):如果已经标记了块b,就返回true。
    • int blockAllocated(ptr b):如果块b是已分配的,就返回true。
    • void markBlock(ptr b):标记块b。
    • int length(ptr b):返回块b的以字为单位的长度(不包括头部)。
    • void unmarkBlock(ptr b):将块b的状态由已标记的改为未标记的。
    • ptr nextBlock(ptr b):返回堆中块b的后继。

C程序中常见的与存储器有关的错误

间接引用坏指针

  • 在进程的虚拟地址空间中有较大的洞,没有映射到任何有意义的数据,如果试图引用一个指向这些洞的指针,操作系统就会以段异常来终止程序。
  • 典型的错误是:scanf("%d",val);,没有加&符号

读未初始化的存储器

  • 虽然bass存储器位置总是被加载器初始化为0,但对于堆存储器却并不是这样的。
  • 常见的错误就是假设堆存储器被初始化为0.

    允许栈缓冲区溢出

  • 如果一个程序不检查输入串的大小就写入栈中的目标缓冲区,程序就会出现缓冲区溢出错误。

    假设指针和指向他们的对象大小是相同的。

  • 一种常见的错误是假设指向对象的指针和他们所指向的对象是大小相同的。

    造成错位错误。

  • 一种很常见的覆盖错误来源

    引用指针,而不是他所指向的对象。

  • 注意C的优先级和结合性

    误解指针运算

  • 忘记了指针的算术操作是以它们指向的对象的大小为单位来进行,而这种大小单位不一定是字节。

    引用不存在的变量

  • 理解栈的规则,有时会引用不再合法的本地变量。

引用空闲堆块中的数据

  • 一个相似的错误是引用已经被释放了的堆块中的数据。

引起存储器泄露

  • 当不小心忘记释放已分配块,而在堆里创建了垃圾时,就会引起存储器泄露。

参考资料

时间: 2024-10-10 20:42:33

20145317《信息安全系统设计基础》第十四周学习总结的相关文章

信息安全系统设计基础第十四周学习总结——20135308

第九章 虚拟存储器 虚拟存储器的三个重要能力: 它将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,高效的使用了主存 它为每个进程提供了一致的地址空间,从而简化了存储器管理 它保护了每个进程的地址空间不被其他进程破坏 第一节 物理和虚拟寻址 1.物理地址 计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组,每字节都有一个唯一的物理地址PA. 根据物理地址寻址的是物理寻址. 2.虚拟地址 虚拟存储器被组织为

信息安全系统设计基础第十四周学习总结

第九章  虚拟存储器 一.虚拟存储器提供了三个重要能力: 1.将主存看作是一个存储在磁盘上的地址空间的高速缓存,在主存中只保护活动的区域,并根据需要在磁盘和主存之间来回传送数据: 2.为每个进程提供了一致的地址空间,从而简化了存储器管理: 3.保护了每个进程的地址空间不被其它进程破坏. 二.理解虚拟存储器的原因: 1.虚拟存储器是中心的:它是硬件异常.硬件地址翻译.主存.磁盘文件和内核软件的交互中心: 2.虚拟存储器是强大的:它可以创建和销毁存储器片.可以映射存储器片映射到磁盘某个部分等等: 3

20135205信息安全系统设计基础第十四周学习总结

第九章 虚拟存储器 虚拟存储器的三个重要能力: 它将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,高效的使用了主存. 它为每个进程提供了一致的地址空间,从而简化了存储器管理 它保护了每个进程的地址空间不被其他进程破坏. 1.物理和虚拟寻址 计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组. 每个字节都有唯一的物理地址. 第一个字节的地址为0,接下来的字节地址为1,在下一个为2,依次类推. 给定这种简单

20135210——信息安全系统设计基础第十四周学习总结

第九章 虚拟存储器 虚拟存储器是硬件异常.硬件地址翻译.主存.磁盘文件和内核软件的完美交互,它为每个进程提供了一个大的.一致的和私有的地址空间. 通过一个很清晰的机制,虚拟存储器提供了三个重要的能力: (1)它将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,它高效地使用了主存. (2)它为每个进程提供了一致的地址空间,从而简化了存储器管理. (3)它保护了每个进程的地址空间不被其他进程破坏. 9.1 物理和虚拟寻址

20135234马启扬-——信息安全系统设计基础第十四周学习总结

第九章 虚拟存储器 主要作用: 将主存看作是一个存储在磁盘上的地址空间的高速缓存,在主存中只保护活动的区域,并根据需要在磁盘和主存之间来回传送数据: 为每个进程提供了一致的地址空间,从而简化了存储器管理: 保护了每个进程的地址空间不被其它进程破坏 9.1 物理和虚拟寻址 1.物理地址 计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组,每字节都有一个唯一的物理地址PA. 根据物理地址寻址的是物理寻址. 2.虚拟地址 虚拟存储器被组织为一个由存放在磁盘上的N个连续的字节大小的单元组成

2017-2018-1 20155305 《信息安全系统设计基础》第四周学习总结(课堂提交作业未来得及提交码云链接myod补充博客)

2017-2018-1 20155305 <信息安全系统设计基础>第四周学习总结(课堂提交作业未来得及提交码云链接myod补充博客) 课堂提交题目要求 编写MyOD.java 用java MyOD XXX实现Linux下od -tx -tc XXX的功能 代码码云链接补交 源代码main函数 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.

2018-2019-1 20165336《信息安全系统设计基础》第四周学习总结

2018-2019-1 20165336<信息安全系统设计基础>第四周学习总结 1.教材学到的知识点 Y86-64中程序员(汇编程序员.编译器等)可见的状态包括程序寄存器.条件码.程序状态.程序计数器(PC).内存 Y86-64中有15个程序寄存器分别是%eax %ecx %edx %ebx %esp %ebp %esi %eadi ZF SF OF PC Stat DMEM Y86-64指令支持的整数操作的长度是8字节 Y86-64的指令编码长度是1-10字节,指令编码长度从1-6个字节不等

2018-2019-1 20165214 《信息安全系统设计基础》第四周学习总结

20165214 2018-2017-1 <信息安全系统设计基础>第四周学习总结 教材学习内容总结 1.ISA的概念:一个处理器支持的指令和指令的字节级编码称为它的指令集体系结构.不同的处理器具有不同的ISA. 2.什么是冒险:一条指令的位置或操作数依赖于其他仍在流水线中的指令. 3.Y86-64有15个程序寄存器,其中%rsp被入栈.出栈.调用和返回指令座位栈指针.标志位ZF.SF.OF保存着最近的算数或逻辑指令所造成影响的有关信息. 4.Y84-64只包括8字节整数操作.指令的字节级编码需

2019-2020-1 20175320 《信息安全系统设计基础》第四周学习总结

2019-2020-1 20175320 <信息安全系统设计基础>第四周学习总结 一.教材学习内容总结 本周我们了解了在计算机系统中信息的表示与处理的方法,主要包括了以下三个方面:进制转换.位的概念与运算.信息的表示.数值运算以及信息的存储. 进制转换 进制转换已经在前面各门课程中多次提及,这里我就不再赘述了. 位的概念 该部分主要介绍了位向量的概念,并介绍了位运算以及逻辑运算,并介绍了两种移位方式,这部分需要注意的是: 注意位运算符号与逻辑运算符号的区别,以及两者计算结果数据类型的区别. 移

2018-2019-1 20165326 《信息安全系统设计基础》第四周学习总结

第四周学习总结 1.程序员可见状态 15个程序寄存器(RF) 3个条件码(CC) 程序状态(Stat) 程序计数器(PC) 内存(DMEM) 2.Y86指令 在Y86当中,寄存器也是有8个,每一个寄存器可以存储一个字,也就是一个32位二进制.条 件码是一个一位二进制的寄存器,保存着最近的算术或逻辑运算所造成的影响的信息.PC则是程序计数器,记录当前正在执行的指令的地址.存储器则是一个很大的字节数组,保存着程序和数据,Y86的程序可以使用虚拟地址(类似于数组的下标)来访问存储器,硬件和操作系统会将