操作系统 原理与实现 LEC3:中断,异常与系统调用

前言

引入:OS如何与外设交互?

外设具有控制器和缓冲区,将输出存入缓冲区
OS获取输入的两种可能方法

  • 轮询:不断读取缓冲区的值
  • 中断:控制器接收到输入后,打断CPU正常执行,OS进行处理

实例:
显示器:60Hz,对CPU而言频率很低,可以采取中断响应
网络:中断+一段时间的轮询(保证快速响应)

应用一般不直接操作设备,而是从OS获取输入(部分用户态驱动除外),例如getchar()调用read()请求OS将输入返回给程序。

通用概念

  • 中断

    • 外部硬件设备产生的信号。
    • 中断是异步的,产生的原因和当前执行的指令无关。
  • 异常

    • 软件程序执行产生的事件,包括系统调用。
    • 异常是同步的,产生和执行与当前执行或试图执行的指令有关。

不同体系结构术语的对应关系
image
之后提到的中断、异常采取上面的通用概念。

AArch64的中断(异步异常)

  • 重置(Reset)
    • 最高级别的异常
    • 由系统上电,控制软件,Watchdog等触发
  • 中断(Interrupt)
    • CPU外部信号触发,打断当前执行
    • 如计时器中断、键盘中断等

AArch64的异常(同步异常)

  • 中止(Abort)
    失败的指令获取或数据访问
  • 异常产生执行
    • SVC(Supervisor Call)
      当用户空间通过系统调用陷入到内核空间的时候,则最终会通过SVC指令进入到内核空间
    • HVC(Hypervisor Call)
      当在ARMv8-A架构下,normal world, EL1尝试去访问EL2的时候,则会陷入到虚拟化层的,其中是通过HVC指令
    • SMC(Secure Moniter Call)
      用于切换noramal world 和 secure world使用。

中断的产生

AArch64中断(异步异常)的产生

早期:向量中断控制器。
ARM处理器中的GIC(Genetal Interrupt Controller)可以管理中断。
需要考虑的问题:

  • 如何定义优先级
  • 交给谁处理
  • 如何与软件协同

AArch64中断(异步异常)的分类

  • IRQ
    普通中断,优先级低,处理慢。
  • FIQ
    快速中断,优先级高,处理快。
    一次只能有一个FIQ,常为可信任的中断源预留。

IRQ和FIQ连接CPU的不同针脚,由GIC进行控制。

  • SError
    难以定位和处理的异常,多由异步中止导致。

GIC中断来源

如图所示
image

  • SPI 共享外围中断

    • 由所有CPU共同连接的设备触发
    • 可以被路由到一个或多个核,找到可用的核进行处理
    • Distributor可配置路由
    • 如UART中断
    • 中断ID:32-1019 4096-5119
  • PPI 私有设备中断

    • 由每个处理器核上的私有设备触发
    • 指定核处理
    • 如通用定时器(Generic Timer)
    • 中断ID:16-31 1056-5119
  • SGI 软件产生中断

    • 发送核间中断进行通信
    • 中断ID:0-15

GIC的路由配置

以启用Timer为例:使用MMIO,设置GIC中寄存器,启用timer
image

GIC中断信息获取

使用MMIO,从GIC中的寄存
器里获得中断信息
image

Linux中的中断处理

  • 尽快返回 + 延迟处理
  • Top Half + Bottom Half

中断处理中的一些约束

  • 不能睡眠或者调用可能会睡眠的任务
  • 不能调用schedule()调度
  • 不能释放信号或调用可能睡眠的操作
  • 不能和用户地址空间交换数据

中断和异常的处理

处理流程

image

中断和异常处理的必做事项

  • 进入中断或异常时
    • 需保存处理器状态,方便之后恢复执行
    • 需准备好在高特权级下进行执行的环境
    • 需选择合适的异常处理器代码进行执行
    • 需保证用户态和内核态之间的隔离
  • 处理时
    • 需获得关于异常的信息,如系统调用参数、错误原因等
  • 返回时
    • 需恢复处理器状态,返回低特权级,继续正常执行流

AArch64的异常处理流程

image

异常发生-信息保存,切换到EL1

异常或中断发生后,硬件会将错误码和部分上下文信息存储在寄存器中
– 处理器状态(PSTATE)-> Saved Program Status Register
(SPSR_EL1)
– 当前指令地址(PC)-> Exception Link Register(ELR_EL1)
– 异常发生原因 ->

  1. Serror与异常:Exception Syndrome Register(ESR_EL1)
  2. 中断:GIC中的寄存器(使用MMIO读取)
    • 安全性问题
    – 上述寄存器均不可在用户态(EL0)中访问
    • 硬件会适当修改处理器状态(PSTATE),进入EL1执行
    • 问题:栈内存的安全性
    – 进入EL1级别后,栈指针(SP)会自动换用SP_EL1
    – 从而实现用户栈->内核栈
    – 如需在EL1下使用SP_EL0作为栈指针,可配置SPSel寄存器

异常处理-寻址handler

• 使用异常向量表(Exception Vector Table)
– 每个异常级别存在独立的异常向量表
– 表项为异常向量(Exception Vector),是处理异常或跳转
到异常handler的小段汇编代码
– 地址位于VBAR_EL1寄存器中
– 选择表项取决于
• 异常类型(同步、IRQ、FIQ、Serror)
• 异常发生的特权级
• 异常发生时的处理器状态(使用的栈指针/运行状态)

返回

eret 指令
– ELR_EL1 -> PC,恢复PC状态
– SPSR_EL1 -> PSTATE,恢复处理器状态
– 降至EL0,硬件自动使用SP_EL0作为栈指针
– 恢复执行

chcore的异常处理

image

image

image

系统调用

  • 指运行在用户空间的程序向操作系统内核请求需要更
    高权限运行的服务
  • 系统调用提供用户程序与操作系统之间的接口





posted @ 2023-03-20 17:08  _vv123  阅读(99)  评论(0编辑  收藏  举报