03启动、中断、异常和系统调用
- 对应视频内容:
- 2.1 操作系统的启动
- 2.2 中断、异常和系统调用
- 一、操作系统的启动
- 通电之后,如何启动。
- BIOS加载Bootloader
- Bootloader的主要工作为
- 二、系统调用,异常,中断
- 为什么应用程序不能直接访问外设呢?(必须要经过操作系统?)
- 操作系统如何设计和实现中断、异常和系统调用
- 三、中断、异常和系统调用
- 硬件
- 软件
- 异常
- 系统调用
- 用户态
- 内核态
- 用户态转换成内核态
- 函数调用和系统调用区别
- 跨越操作系统边界的开销
对应视频内容:
2.1 操作系统的启动
2.2 中断、异常和系统调用
一、操作系统的启动
通电之后,如何启动。
DISK: 存放OS
BIOS: 基本I/O处理系统:在计算机开机的时候,检测各种外设。然后加载相应的软件来执行。
Bootloader:用于加载OS。
开始加电时,BIOS从CS:IP这个地址开始执行,之后完成一系列工作,包括:POST(加电自检),寻找显卡和执行BIOS等。
BIOS加载Bootloader
Bootloader放在硬盘的第一个主引导扇区(512字节)。BIOS从硬盘的第一个扇区寻找,一下便找到Bootloader,Bootloader再负责加载OS。
Bootloader在内存的其实地址为0X7C00.
Bootloader的主要工作为
- 将操作系统的代码和数据从硬盘加载到内存中。
- 控制权交给到OS,跳转到OS的地址。
二、系统调用,异常,中断
- 操作系统面向外设,通过中断和I/O进行处理;
- 操作系统面向应用程序通过系统调用和异常提供支持。
定义
-
系统调用(来源于应用程序):应用程序主动向操作系统发出服务请求;
-
异常(来源于不良的应用程序):非法指令或者其他坏的处理状态(如:内存出错);
-
中断(来源于外设):来自不同的硬件设备的计时器和网络中断。
为什么应用程序不能直接访问外设呢?(必须要经过操作系统?)
操作系统可以屏蔽底层的复杂性和差异性。
- 在计算机运行中,内核是被信任的第三方;
- 只有内核可以执行特权指令
- 方便应用程序开发
操作系统如何设计和实现中断、异常和系统调用
从源头区分
- 中断: 外设(即非CPU产生)
- 键盘敲击,鼠标移动事件,网卡可以产生网络包,声卡,等等都可以称为中断事件。
- 异常: 应用程序意想不到的行为
- 除零操作
- 系统调用: 应用程序请求操作提供服务
- 读写文件
- 发送网络包
从处理时间区分
- 中断: 异步(不知什么时候产生)
- 异常: 同步(由指令确定时间)
- 系统调用: 异步或同步(发出请求的点是同步的,但是获取返回的点可能是异步的)
从响应区分
- 中断: 持续,对用户应用程序是透明的(感觉不到)
- 异常: 杀死或者重新执行意想不到的程序指令
- 系统调用: 等待和持续
三、中断、异常和系统调用
中断、异常都有针对软硬件的处理过程。对中断和异常进行编号(中断表),编号对应特定地址,跳到处理历程,解决问题。
但是,中断打断了一个程序的正常执行,因此要设置保护与恢复机制。
硬件
- 设置中断标记(CPU初始化)
- 将内部、外部事件设置中断标记,产生中断号,来找到对应的处理历程。
软件
- 保存当前处理状态(便于程序从被打断的点继续执行);
- 中断服务程序处理;
- 网卡中断,处理网络报处理
- 清除中断标记;
- 恢复之前保存的处理状态。因此,应用程序完全不用感知到中断的产生。
异常
- 异常编号:
- 保存现场;
- 异常处理
- 杀死了产生异常的程序
- 重新执行异常指令
- 恢复现场
系统调用
例:标准C库的例子。
应用程序调用printf()时,会触发系统调用write()。
程序访问主要是通过高层次API接口而不是直接进行系统调用。例如:
- Win32 API 用于 Windows
- POSIX API 用于POSIX-based systems(包括UNIX,LINUX,Mac OS X的所用版本)
- Java API用于JAVA虚拟机(JVM),JVM再访问Win32 API等
用户态
程序的用户态是指级别比较低的状态;
- 无法执行特权指令
- 无法控制IO
内核态
操作系统的内核态是等级最高的状态。
用户态转换成内核态
应用程序发出系统调用之后,要切换堆栈(操作系统堆栈与其不同),也要实现由用户态到内核态的转换。
函数调用和系统调用区别
跨越操作系统边界的开销
- 在执行时间上的开销超过程序调用
- 开销
- 建立中断/异常/系统调用号与对应服务
- 建立内核堆栈
- 验证参数(操作系统并不信任程序,要花费时间检查参数)
- 内核态映射到用户态的地址空间,不能使用简单的改变指针的方法,要拷贝
- 更新页面映射权限
- 内核态独立地址空间 TLB
的开销
- 在执行时间上的开销超过程序调用
- 开销
- 建立中断/异常/系统调用号与对应服务
- 建立内核堆栈
- 验证参数(操作系统并不信任程序,要花费时间检查参数)
- 内核态映射到用户态的地址空间,不能使用简单的改变指针的方法,要拷贝
- 更新页面映射权限
- 内核态独立地址空间 TLB