20145335 《信息安全系统设计基础》第十四周学习总结
教材学习内容总结
物理和虚拟寻址
计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组。每宇节都有一个唯一的物理地址 。第一个字节的地址为 0,接下来的字节地址为 1,再下一个为 2, CPU 访问存储器的最自然的方式就是使用物理地址。我们把这种方式称为物理寻址。
早期的 PC 使用物理寻址,现代处理器使用的是一种称为虚拟寻址的寻址形式。
使用虚拟寻址时, CPU 通过生成一个虚拟地址来访问主存,这个虚拟地址在被送到存储器之前先转换成适当的物理地址。将一个虚拟地址转换为物理地址的任务叫做地址翻译。地址翻译需要 CPU 硬件和操作系统之间的紧密合作。 CPU 芯片上叫做存储器管理单元的专用硬件, 利用存放在主存中的查询表来动态翻译虚拟地址。注意:该表的内容是由操作系统管理的。
地址空间
-
线性地址空间:地址空间中的整数是连续的
-
虚拟地址空间:CPU从一个有
N=2^n
个地址的地址空间中生成的虚拟地址 -
物理地址空间:与系统中的物理存储器的M个字节相对应
-
一个地址空间的大小是由表示最大地址所需要的位数来描述的。
虚拟存储器作为缓存的工具
-
概述:
虚拟存储器被组织为一个由存放在磁盘上的 N个连续的字节大小的单元组成的数组。每字节都有一个唯一的虚拟地址,这个唯一的虚拟地址是作为到数组的索引的。磁盘上数组的内容被缓存在主存中。磁盘上的数据被分割成块,这些块作为磁盘和主存之间的传输单元。
-
DRAM
缓存的组织结构SRAM 缓存位于 CPU 和主存之间的 Ll、 L2 和 L3 高速缓存。
DRAM 缓存来表示虚拟存储器系统的缓存,它在主存中缓存虚拟页。
在存储层次结构中, DRAM 缓存的位置对它的组织结构有很大的影响。
DRAM 缓存中的不命中比起 SRAM 缓存中的不命中要昂贵得多,因为 DRAM 缓存不命中要由磁盘来服务,而 SRAM 缓存不命中通常是由基于 DRAM 的主存来服务的。
DRAM 缓存的组织结构完全是由巨大的不命中开销驱动的。
-
页表、页命中、缺页
页表:是一个数据结构,存放在物理存储器中,将虚拟页映射到物理页,就是一个页表条目的数组
页表就是一个页表条目的数组
PTE:由一个有效位和一个n位地址字段组成的
DRAM
缓存不命中称为缺页在磁盘和存储器之间传送页的活动叫做交换或者页面调度
颠簸:工作集大小超出了物理存储器的大小
虚拟存储器作为存储器管理的工具
-
多个虚拟页面可以映射到同一个共享物理页面上
-
简化链接:独立的地址空间允许每个进程的存储器映像使用相同的基本格式,而不管代码和数据实际存放在物理存储器的何处
-
简化加载:虚拟存储器使得容易想存储器中加载可执行文件和共享对象文件
-
简化共享:独立地址空间为操作系统提供了一个管理用户进程和操作系统自身之间共享的一致机制
-
简化存储器分配:虚拟存储器为向用户进程提供一个简单的分配额外存储器的机制
虚拟存储器作为存储器保护的工具
-
PTE
的三个许可位:SUP:表示进程是否必须运行在内核模式下才能访问该页
READ:读权限
WRITE:写权限
地址翻译
-
地址翻译:是一个N元素的虚拟地址空间中的元素和一个M元素的物理地址空间中元素之间的映射。
-
页表基址寄存器:
CPU中的一个控制寄存器,叫做页表基址寄存器指向当前页表。N位的虚拟地址包含两个部分:一个p位的
VPO
(虚拟页面偏移)和一个n-p
位的VPN
。MMU
利用VPN来选择适当的PTE
。将页表条目中PPN(物理页号)和虚拟地址中的VPO串联起来,就是相应的物理地址。 -
页面命中完全由硬件处理的,而处理缺页要求硬件和OS内核协作完成。
-
结合高速缓存和虚拟存储器
大多数系统是选择物理寻址的方式来访问高速缓存。使用物理寻址,多个进程同时在高速缓存中有存储块和共享来自相同虚拟页面的块成为简单的事情。而且,高速缓存无需处理保护的问题,因为访问权限的检查是地址翻译过程中一部分。
-
利用TLB加速地址翻译
在
MMU
中包括一个关于PTE
的小的缓存,称为TLB
。TLB
是一个小的,虚拟寻址的缓存,其中每一行都保存着一个由单个PTE
组成的块。 -
多级页表
多级页表——采用层次结构,用来压缩页表。
储存器映射
-
共享对象和私有对象
- 共享对象 - 私有对象 于`execve`函数: enter description here
-
使用
mmap
函数的用户级存储器映射- 创建新的虚拟存储器区域 #include <unistd.h> #include <sys/mman.h> void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
-
参数含义:
- `start`:这个区域从start开始 - `fd`:文件描述符 - `length`:连续的对象片大小 - `offset`:距文件开始处的偏移量 - `prot`:访问权限位,具体如下: PROT_EXEC:由可以被CPU执行的指令组成 PROT_READ:可读 PROT_WRITE:可写 PROT_NONE:不能被访问 - `flag`:由描述被映射对象类型的位组成,具体如下: MAP_ANON:匿名对象,虚拟页面是二进制0 MAP_PRIVATE:私有的、写时拷贝的对象 MAP_SHARED:共享对象
-
删除虚拟存储器:
include <unistd.h> include <sys/mman.h> int munmap(void *start, size_t length); 成功返回0,失败返回-1 从`start`开始删除,由接下来`length`字节组成的区域。
动态存储器分配
-
malloc
和free
函数:malloc
函数:从堆中分配块:#include <stdlib.h> void *malloc(size_t size);
free
函数:释放已分配的堆块:#include <stdlib.h> void free(void *ptr);
-
碎片:分为内部碎片和外部碎片
-
放置策略:首次适配、下一次适配、最佳适配
-
申请额外的堆存储器:
sbrk
函数:#include <unistd.h> vid *sbrk(intptr_t incr);
成功则返回旧的
brk
指针,出错为-1通过将内核的
brk
指针增加incr
来扩展和收缩堆。 -
实现简单的分配器:序言块和结尾块
-
显式空闲链表的区别
-
分配时间
隐式:分配时间是块总数的线性时间
显式:分配时间是空闲块数量的线性时间。
- 链表形式 隐式:隐式空闲链表 显式:双向链表,有前驱和后继,比头部脚部好使。
-
垃圾收集
-
基本知识:垃圾收集器
-
Mark&Sweep
垃圾收集器两个阶段:标记、清除
相关函数:
ptr定义为typedef void *ptr 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语言不会用类型标记来标记存储器位置。
C程序中常见的与存储器有关的错误
-
间接引用坏指针:
scanf
错误 -
读未初始化的存储器:假设堆存储器被初始化为0
-
允许栈缓冲区溢出:缓冲区溢出错误
-
假设指针和它们指向的对象是相同大小的
-
造成错位错误
-
引用指针,而不是它所指向的对象
-
误解指针运算
-
引用不存在的变量
-
引用空堆块中的数据
-
引起存储器泄露
本周代码托管链接
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | 掌握核心的linux命令,了解了linux操作系统 |
第二周 | 300/500 | 2/4 | 18/38 | 学会了虚拟机上的C编程 |
第三周 | 500/1000 | 3/7 | 22/60 | 初步学习计算机中各种数的表示和运算 |
第五周 | 300/1300 | 2/9 | 30/90 | 通过学习汇编,了解逆向的思想应用 |
第六周 | 300/1500 | 2/11 | 28/110 | 安装了Y86处理器,了解了ISA抽象 |
第七周 | 150/1700 | 2/13 | 30/130 | 学习了存储器的体系结构| |
第八周 | 200/1900 | 2/15 | 30/150 | 复习前7章知识 |
第九周 | 340/2100 | 1/17 | 31/170 | 学习了系统级I/O |
第十周 | 599/2700 | 1/19 | 33/200 | 学习了Linux命令 |
第十一周 | 1016/3300 | 1/21 | 35/240 | 学习了异常控制流 |
第十二周 | 300/3500 | 3/25 | 30/280 | 复习前三周代码知识点和实验 |
第十三周 | 300/4000 | 2/26 | 34/320 | 学习了网络编程和并发编程 |
第十四周 | 240/4500 | 1/28 | 30/350 | 学习了虚拟存储器 |