异常
-
注:此处的异常是异常(内部且同步)和中断(外部且异步)的总称
-
异常表(即中断向量表):系统启动时,OS分配和初始化一张跳转表,可以根据异常号k定位到第k个条目,这个条目对应一个异常处理程序的入口地址
- 异常触发
- 异常触发:处理器触发异常,根据异常->异常号->查找异常表->定位异常处理程序的入口地址
- 保存环境:将内容保存到栈中
- 保存返回地址:有时是事件发生地址(pc),有时是事件发生地址的下一条地址(snpc=pc+4,假设没有压缩指令)
- 保存GPR:将中断程序所需的寄存器状态保存
- 栈:若指令的特权模式是U,则将内容保存到用户栈中,其余特权同理;但如果指令的特权模式从U->K,则会保存到内核栈中,其余特权转换同理
- 跳转到异常
- 异常处理程序的参数:通过寄存器和栈来传递(这里和函数调用类似)
- 如果后续需要执行上下文切换,异常处理程序还需要将旧ctx的栈改变为新ctx的栈
- 异常返回(可选)
- 异常返回:从栈中获取到返回地址,进行返回
- 恢复环境:从栈中获取到保存内容,进行恢复
- 异常的类别
- 内部异常(同步):自陷trap、故障fault、终止abort
- 自陷:有意的异常,即系统调用(比如程序想要向内核申请服务),因为pc执行成功,所以总是返回到pc+4
- 故障:可恢复的错误,因为pc没有执行成功,为了重新执行以恢复状态,所以总是返回到pc
- 终止:不可恢复的错误,不返回
- 外部中断(异步):中断interrupt
- 中断:来自IO设备的信号
- 系统调用与函数调用的区别:函数调用运行在用户模式,只能使用用户栈和用户级指令;而系统调用运行在内核模式,可以使用内核栈和内核级指令(系统调用范围>函数调用范围)
进程
- 并发流和并行流
- 物理内存、虚拟内存技术、虚拟地址空间
- 利用虚拟内存技术(页表+换入换出),可以将物理内存抽象为:每个进程私有的一块虚拟地址空间
- 虚拟地址空间的内核虚拟内存:结构和用户部分类似,都有代码、数据、运行时堆、栈
- 上下文切换
- 调度:在进程执行的某些时刻,内核可以决定抢占当前进程,然后重新开始一个先前被抢占了的进程
- 切换的来源:由内核或OS的调度器引发自陷(系统调用)来产生上下文切换,有些中断也能产生上下文切换
- 切换的原理:<见异常触发部分>
进程控制
- 进程状态:创建、就绪、运行、阻塞、终止、挂起(就绪挂起、阻塞挂起)
- 调度方式
- 低级调度:内存->CPU,就绪->运行
- 中级调度:外存->内存,阻塞挂起->阻塞/就绪挂起->就绪
-
高级调度:外存->CPU,无->创建->就绪
-
进程控制
-
获取pid:getpid()、getppid()
-
创建:exit(status)
-
终止与回收:fork()(在父进程中返回创建的子进程的pid;在创建的子进程中返回0)、waitpid(pid)
- 如果子进程先终止:终止子进程==(未回收时)==>僵死进程,内核保留部分状态==(回收后)==>内核删除所有状态
- 如果父进程先终止:子进程==>孤儿进程,由init进程来收养(它的新的父进程变为init),并由init负责回收
-
休眠:sleep(secs)、pause()
-
加载并运行程序
-
execve:加载可执行目标文件(比如elf),且带参数列表argv和环境变量列表envp。它和fork不同的是,它没有返回值。
-
程序和进程的区别(execve和fork的区别)
- 程序的定义:是代码和数据,可以在磁盘中,也可以在elf的某几段中;程序运行在某个进程上下文中
- fork:在新的子进程中执行与父进程完全一致的程序(因为子进程是父进程的复制品),即==两个进程一个程序==
- execve:在当前进程中执行不同的新程序,即==一个进程两个程序==
-
信号机制:暂时略
-
阻塞机制:暂时略
物理内存与“虚拟内存技术”
- 物理寻址、虚拟寻址、地址空间
- 存储层次:
- 高速缓存是物理内存的缓存(在全相联SRAM上缓存)
- 物理内存是物理外存的缓存(利用虚拟内存和页表技术,在全相联DRAM上缓存)
内存是外存的缓存
-
目的:将外存(如磁盘)中的部分内容缓存在内存中
-
单元划分:
- 物理外存按块划分,称为物理块,它存在于外存中,它作为外存和内存之间的传输单元
- 虚拟内存按块划分,称为虚拟页(页,VP),它是外存的一个假想的数组(可以说它就在外存中)
- 它负责从外存中拿入一些物理块,然后向物理内存申请缓存它们;它负责从外存中拿出一些物理块,维护外存和内存的一致性
- 实际上一个物理块的每个字节都同时具有物理地址和虚拟地址,物理地址组成物理块的数组,虚拟地址组成虚拟页的数组
- 物理内存按块划分,称为物理页(页帧,PP),它存在于DRAM缓存中
- 使用DRAM的惩罚:miss的惩罚大、替换错误的惩罚大
- 所以DRAM一般使用读分配、写回写分配,使得尽量减少与外存的交互
- 单个虚拟页的三种状态:未分配、已缓存、未缓存
- 未分配:没有将虚拟页分配到物理块上,即虚拟页和物理块无映射(物理块<=>虚拟页)
- 未缓存:已将虚拟页分配到物理块上,但没有将虚拟页缓存至物理页上,即虚拟页和物理页无映射(物理块<=>虚拟页<==/=>物理页)
- 已缓存:已将虚拟页分配到物理块上,也已将虚拟页缓存至物理页上,即有映射(物理块<=>虚拟页<=>物理页)
- 映射关系的维护
- 页表可以维护”虚拟页<=>物理页“的映射关系
- 替换算法可以维护”物理块<=>虚拟页“的映射关系(通过换入换出)
页表
- 组成:由一个有效位和地址组成
- 当有效时,说明存在”虚拟页<=>物理页“的映射,此时根据虚拟页找到的地址应该指向物理页
- 即虚拟地址->页表索引->页表地址(不空闲)->物理页地址
- 当无效时,说明不存在映射,此时根据空闲虚拟页找到的地址应该指向虚拟也
- 即虚拟地址->页表索引->页表地址(空闲)->空闲的虚拟页地址
-
虽然虚拟页在外存,但是页表存在于内存
-
页命中流程
- CPU访问一个虚拟地址A
- 地址翻译硬件MMU将A转换为页表的索引,在页表中查找对应项
- 对应项的有效位为1,则页命中,说明内存缓存了该数据,页表给出对应的物理页地址
- CPU访问该物理页地址
- 页缺失流程
- CPU访问一个虚拟地址A
- 地址翻译硬件MMU将A转换为页表的索引,在页表中查找对应项
- 对应项的有效位为0,则页缺失,说明内存没有缓存该数据,触发缺页中断
- 中断处理程序会通过替换算法,进行页的换入换出(注:使用读分配、写回写分配的读写操作)
- 选出一个”牺牲页“,使用将内存的物理页写回到外存
- 然后将待访问的页,从外存调入到内存中
- 缺页程序会重新执行导致缺页中断的命令(此时返回地址就是pc,而不是pc+4)