1、启动
- DISK:存放OS
- BIOS:基本I/O处理系统(检查外设,然后才可以加载软件开始执行)
- Bootloader:加载OS(从硬盘加载到内存,让CPU可以执行操作系统)
- POST(加电自检):寻找显卡和执行BIOS
2、中断、异常和系统调用
2.1 应用程序为什么不能直接访问外设,而是要通过操作系统?
- 在计算机运行中,应用程序是不可信任的,内核是被信任的第三方
- 给上层建筑提供更简单统一的接口,屏蔽底层的复杂性和差异性
2.2 定义
- 系统调用(来源于应用程序):应用程序主动向操作系统发出服务请求(一条特殊的指令)
- 异常(来源于不良的应用程序):非法指令或者其他坏的处理状态(如内存出错)
- 中断(来源于外设):来自不同的硬件设备的计时器和网络的中断
2.3 中断、异常和系统调用比较
- 源头:
- 中断:外设
- 异常:应用程序意想不到的行为
- 系统调用:应用程序请求操作系统提供服务
- 处理时间:
- 中断:异步
- 异常:同步
- 系统调用:同步或异步
- 响应:
- 中断:应用程序持续进行,对用户应用程序是透明的
- 异常:杀死应用程序或者重新执行意想不到的应用程序指令
- 系统调用:等待和持续
2.4 中断处理机制
- 硬件:设置中断标记(CPU初始化)
- 将内部、外部事件设置中断标记
- 中断事件的ID
- 软件(操作系统)
- 保存当前处理状态(便于后续恢复)
- 中断服务程序处理
- 清除中断标记
- 恢复之前保存的处理状态
*即之前所说的应用程序是透明的,应用程序感知不到中断程序的产生
2.5 异常处理机制
- 保存现场
- 异常处理
- 杀死产生异常的程序
- 重新执行异常指令(注意是重新执行修补好的)
- 恢复现场
2.6 系统调用的原理
- 应用程序需要操作系统提供服务,操作系统需要提供接口,即系统调用接口
- 程序访问主要是通过高层次的API接口而不是直接进行系统调用
- Win32 API 用于Windows
- POSIX API 用于POSIX-based systems(包括Unix,Linux,Mas OS X 的所有版本)
- Java API 用于Java虚拟机(JVM)(不属于操作系统的API接口,最终都是使用当前所处的系统的API)
- 程序调用和系统调用的不同之处
- 系统调用要完成栈切换,以及状态转变,时间更长;
- 程序调用在栈内处理并产生结果
2.7 系统调用的实现
- 需要完成从用户态到内核态的转换
3、跨越操作系统边界的开销
- 执行时间超过程序调用
- 开销(值得且必须的,保证操作系统在安全可靠的环境下执行)
- 建立中断/异常/系统调用号与对应服务例程映射关系的初始化开销
- 操作系统拥有自己的堆栈,建立内核堆栈(保存和恢复的处理开销)
- 验证参数(对应用程序不信任而需要进行参数验证)
- 内核态映射到用户态的地址空间;更新页面映射权限
- 内核态独立地址空间(TLB)