操作系统组成

  • CPU
  • Memory
  • I/O

Disk:存放OS

BIOS:基本I/O系统(检测外设,加载软件)

Bootloader:加载OS

操作系统启动

  1. 通电之后,从指定地址开始执行

x86开机时,设置 CS:IP = 0xf000:fff0

CS:段寄存器

IP:指令寄存器

  1. POST(加电自检),寻找显卡和执行BIOS

寻址0xffff0:ROM BIOS映射区

如输入输出设备等

  1. BIOS加载Bootloader

Bootloader通常在BIOS紧接着512字节地址,把磁盘0磁道0扇区读入0x7c00处

设置CS=0x07c0,IP=0x0000

  1. Bootloader加载OS,把OS复制到内存中

  2. CPU控制权交给OS,从OS的第一个地址开始执行

操作系统与设备和程序交互

系统调用、异常、中断

定义

  • 系统调用(来源于应用程序)
    • 应用程序主动向操作系统发出服务请求
  • 异常(来源于不良的应用程序)
    • 非法指令或者其他坏的处理状态(内存出错)
  • 中断(来源于外设)
    • 来自不同的硬件设备计时器和网络的中断

在计算机中,内核是被信任的第三方

只有内核可以执行特权指令

为了方便应用程序

源头

  • 中断:外设
  • 异常:应用程序意想不到的行为
  • 系统调用:应用程序请求操作提供服务

处理时间

  • 中断:异步
  • 异常:同步
  • 系统调用:异步或同步

响应

  • 中断:持续,对应用程序是透明的
  • 异常:杀死或者重新执行异常指令
  • 系统调用:等待和持续

中断处理

硬件

设置中断标记

  1. 将内部、外部事件设置中断标记
  2. 中断时间的ID

软件

  • 保存当前处理状态
  • 中断服务程序处理
  • 清除中断标记
  • 恢复之前保存的处理状态

应用程序透明

异常处理

异常:异常编号

  • 保存现场
  • 异常处理
    • 杀死产生异常的程序
    • 重新执行异常命令
  • 恢复现场

应用程序透明

系统调用

  • 应用程序调用printf()时,会触发系统调用write(),告诉系统需要把数据写到哪里,如屏幕,完毕后操作系统返回结果
  • 程序访问主要是通过高层次的API接口而不是直接进行系统调用
    • Win32API用于Windows
    • POSIX API用于POSIX-based systems,包括UNIX,LINUX,MAC OS X所有版本
    • Java API用于JVM(底层调用Win32API或POSIX API)

当应用程序执行系统调用时,会发生一个用户态到内核态的转换,操作系统对系统调用的参数和ID进行识别和完成具体服务

系统调用和函数调用的区别

  1. 当应用程序发出函数调用,在一个栈中完成参数传递和返回
  2. 系统调用时,应用程序和操作系统有各自的堆栈,切换特权级时也需要切换堆栈,需要额外的开销,回报是安全可靠

用户态和内核态

用户态

指的是在应用程序执行过程中CPU所处的特权级的状态,用户态特权级较低,不能直接访问某些特殊的机器指令和IO

内核态

操作系统可以执行任何一条指令,包括特权指令、IO指令,完全控制整个计算机系统

总结

系统调用、中断和异常跨越了操作系统和应用程序,操作系统和外设的边界,代价是确保系统安全可靠正常

  • 执行时间上的开销超过程序调用
  • 开销
    • 建立中断/异常/系统调用号与对应服务例程映射关系的初始化开销
    • 建立内核堆栈:保存和恢复
    • 验证参数:安全
    • 内核态映射到用户态的地址空间、更新页面映射权限:内核态执行完毕后的内存拷贝
    • 内核态独立地址空间:TLB

开销是值得的和必须的,保证操作系统安全可靠的环境中执行