操作系统组成
- CPU
- Memory
- I/O
Disk:存放OS
BIOS:基本I/O系统(检测外设,加载软件)
Bootloader:加载OS
操作系统启动
- 通电之后,从指定地址开始执行
x86开机时,设置 CS:IP = 0xf000:fff0
CS:段寄存器
IP:指令寄存器
- POST(加电自检),寻找显卡和执行BIOS
寻址0xffff0:ROM BIOS映射区
如输入输出设备等
- BIOS加载Bootloader
Bootloader通常在BIOS紧接着512字节地址,把磁盘0磁道0扇区读入0x7c00处
设置CS=0x07c0,IP=0x0000
Bootloader加载OS,把OS复制到内存中
CPU控制权交给OS,从OS的第一个地址开始执行
操作系统与设备和程序交互
系统调用、异常、中断
定义
- 系统调用(来源于应用程序)
- 应用程序主动向操作系统发出服务请求
- 异常(来源于不良的应用程序)
- 非法指令或者其他坏的处理状态(内存出错)
- 中断(来源于外设)
- 来自不同的硬件设备计时器和网络的中断
在计算机中,内核是被信任的第三方
只有内核可以执行特权指令
为了方便应用程序
源头
- 中断:外设
- 异常:应用程序意想不到的行为
- 系统调用:应用程序请求操作提供服务
处理时间
- 中断:异步
- 异常:同步
- 系统调用:异步或同步
响应
- 中断:持续,对应用程序是透明的
- 异常:杀死或者重新执行异常指令
- 系统调用:等待和持续
中断处理
硬件
设置中断标记
- 将内部、外部事件设置中断标记
- 中断时间的ID
软件
- 保存当前处理状态
- 中断服务程序处理
- 清除中断标记
- 恢复之前保存的处理状态
应用程序透明
异常处理
异常:异常编号
- 保存现场
- 异常处理
- 杀死产生异常的程序
- 重新执行异常命令
- 恢复现场
应用程序透明
系统调用
- 应用程序调用printf()时,会触发系统调用write(),告诉系统需要把数据写到哪里,如屏幕,完毕后操作系统返回结果
- 程序访问主要是通过高层次的API接口而不是直接进行系统调用
- Win32API用于Windows
- POSIX API用于POSIX-based systems,包括UNIX,LINUX,MAC OS X所有版本
- Java API用于JVM(底层调用Win32API或POSIX API)
当应用程序执行系统调用时,会发生一个用户态到内核态的转换,操作系统对系统调用的参数和ID进行识别和完成具体服务
系统调用和函数调用的区别
- 当应用程序发出函数调用,在一个栈中完成参数传递和返回
- 系统调用时,应用程序和操作系统有各自的堆栈,切换特权级时也需要切换堆栈,需要额外的开销,回报是安全可靠
用户态和内核态
用户态
指的是在应用程序执行过程中CPU所处的特权级的状态,用户态特权级较低,不能直接访问某些特殊的机器指令和IO
内核态
操作系统可以执行任何一条指令,包括特权指令、IO指令,完全控制整个计算机系统
总结
系统调用、中断和异常跨越了操作系统和应用程序,操作系统和外设的边界,代价是确保系统安全可靠正常
- 执行时间上的开销超过程序调用
- 开销
- 建立中断/异常/系统调用号与对应服务例程映射关系的初始化开销
- 建立内核堆栈:保存和恢复
- 验证参数:安全
- 内核态映射到用户态的地址空间、更新页面映射权限:内核态执行完毕后的内存拷贝
- 内核态独立地址空间:TLB
开销是值得的和必须的,保证操作系统安全可靠的环境中执行