CNMOOC-os- ch2硬件基础

资料来源于上海交通大学 并行与分布式系统研究所

2.4  中断与异常的概念

通用概念:
中断(Interrupt)

  1. 外部硬件设备所产生的信号
  2. 异步:产生原因和当前执行指令无关,如程序被磁盘读打断

异常(Exception)

  1. 软件的程序执行而产生的事件
  2. 包括系统调用(SystemCall)
  3. 用户程序请求操作系统提供服务
  4. 同步:产生和当前执行或试图执行的指令相关

不同体系结构术语的对应关系:

通用概念产生原因AArch64X86-64
中断硬件异步异步异常(重置,中断)中断(可屏蔽,不可屏蔽)
异常软件同步同步异常(终止,异常指令)异常(Fault, trap, abort)

之后提到的
“异常”均为通用概念意义

AArch64的中断(异步异常)

  • 重置(Reset)
    最高级别的异常,用以执行代码初始化CPU核心
    由系统首次上电或控制软件、Watchdog等触发

  • 中断(Interrupt)
    CPU外部的信号触发,打断当前执行
    一如计时器中断、键盘中断等

AArch64的(同步)异常

  • 中止(Abort)
    失败的指令获取或数据访问
    如访问不可读的内存地址等
  • 异常产生指令(Exceptiongeneratinginstructions)
    -SVC:用户程序->操作系统
    -HVC:客户系统->虚拟机管理器
    -SMC:NormalWorld->SecureWorld

X86-64术语

  • 中断(设备产生、异步)
    可屏蔽:设备产生的信号,通过中断控制器与处理器相连,可被
    暂时屏蔽(如,键盘、网络事件)
    不可屏蔽:一些关键硬件的崩满(如,内存校验错误)

  • 异常(软件产生、同步)
    错误(Fault):如缺页异常(可恢复)、段错误(不可恢复)等
    陷阱(Trap):无需恢复,如断点(int3)、系统调用(int80)
    中止(Abort):严重的错误,不可恢复(机器检查)

2.5  中断与异常的产生

在这里插入图片描述

中断控制器需要考虑的问题

  • 如何指定不同中断的优先级
    低优先级中断处理中,出现了高优先级的中断
    嵌套中断
  • 中断交给谁处理
  • 如何与软件协同

AArch64中断的分类

  • IRQ(Interrupt Request)
    普通中断,优先级低,处理慢

  • FIQ(Fast Interrupt Request)

    1. 一次只能有一个FIQ
  1. 快速中断,优先级高,处理快
  2. 常为可信任的中断源预备

以上IRQ, FIQ, 连接CPU的不同针脚, 可在中断控制器(Interrupt Controller)中配置;

  • SError(SystemError)
    原因难以定位、较难处理的异常,多由异步中止(Abort)导致
    如从缓存行(Cacheline)写回至内存时发生的异常;

早期的ARM中断控制器
厂商指定模型

  • 将中断路由给处理器的功能
    由Soc厂商实现

  • FIQ直接发给处理器,IRC根据优先级进行分发

  • Freescale/NXP iMx233/iMx28系列中的
    ICOLL

早期的ARM中断控制器

  • 向量中断控制器 VIC(Vector Interrupt Controller)

  • ARM提出
    放在AMBA(AdvancedMicrocontrollerBus Architecture)高速总线上

  • 32种非向量中断(不同中断, 相同的处理入口)

  • 16种向量中断(不同中断,不同的处理入口)

在这里插入图片描述

GIC:通用中断控制器

  • 中断类型变多,将中断分发给不同的核(对称或非称)进行处理

主要功能

  • 分发:管理所有中断、决定优先级、路由
  • CPU接口:给每个CPU核有对应的接口;

GIC中断来源
SPI:共享外围中断

  • 可以被路由到一个或多个核,找到可用的核进行处理
  • Distributor可配置路由
  • 如UART中断
  • 中断ID:32-1019;

在这里插入图片描述

PPI:私有外围中断

  • 指定核处理
  • Distributor可配置路由
    -如WatchingDog ->A5 core
  • 中断ID:16-31

SGI:软件产生中断
核间通信
中断ID:0-15

在这里插入图片描述
gic 中断信息获取,

MMIO(Memory mapping I/O)即内存映射I/O,它是PCI规范的一部分,I/O设备被放置在内存空间而不是I/O空间。从处理器的角度看,内存映射I/O后系统设备访问起来和内存一样。这样访问AGP/PCI-E显卡上的帧缓存,BIOS,PCI设备就可以使用读写内存一样的汇编指令完成,简化了程序设计的难度和接口的复杂性。
在这里插入图片描述

2.6 Linux 的中断处理理念

案例:Linux的中断处理理念

  • 在中断处理中做尽量少的事
  • 推迟非关键行为
  • 结构:Top half & Bottom half
  • Top half:做最少的工作后返回
  • Bottom half: 推迟处理(softirg,tasklets,工作队列,内核线程)

Top half:
Bottom half: taskle, Softirq, work queue, kernel thread



TopHalf:马上做

  • 最小的、公共行为:
    保存寄存器、屏蔽其他中断 ;
    恢复寄存器,返回原来场景;

  • 最重要:调用合适的由硬件驱动提供的中断处理handler

  • 因为中断被屏蔽,所以不要做太多事情(时间、空间)

  • 使用将请求放入队列,或者设置标志位将其他处理推退到bottom half

TopHalf:找到中断处理 handler

  • 现代处理器中,多个I/O设备共享一个IRQ和中断向量

  • 多个ISR(interrupt service routines)可以结合在一个向量上

  • 调用每个设备对应该IRQ的ISR

BottomHalf:延迟完成

  • 提供一些推迟完成任务的机制
    -softirqs
    -tasklets(建立在softirqs之上)
    一工作队列
    -内核线程

  • 这些工作可以被中断

注意:中断处理没有进程上下文
为什么?

  • 中断(和异常相比)和具体的某条指令无关
  • 也和中断时正在跑的进程, 用户程序无关
  • 中断处理handler不能睡眠!

中断处理中的一些约束

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

2.7 中断与异常的处理

处理流程
正常执行

进入异常和中断处理
选择合适的handler
CPU发现中新或异常
处理
从handler中返回

在这里插入图片描述

中断与异常的处理使用同一套机制,差异仅在选择handler中体现。

中断和异常处理必做事项
进入中断或异常时

  • 需保存处理器状态,方便之后恢复执行
  • 需准备好在高特权级下进行执行的环境
  • 需选择合适的异常处理器代码进行执行
  • 需保证用户态和内核态之间的隔离

处理时:

  • 需获得关于异常的信息,如系统调用参数、错误原因等
    返回时:
    需恢复处理器状态,返回低特权级,继续正常执行流

AArch64的中断和异常处理
在这里插入图片描述

查询异常向量表
(ExceptionVectorTable
选择handler
EL0下的正常执行流

发生中断或异常
处理
继续ELO下的正常执行
eret

  • 以ELO-EL1为例,后同

发生-信息保存

  • 异常或中断发生后,硬件会将错误码和部分上下文信息存储在寄存器中.
  • 处理器状态(PSTATE)-> Saved Program Status Register(SPSREL1)
  • 当前指令地址(PC)-> Exception Link Register(ELR_EL1)
    异常发生原因-
    1)Serror与异常:Exception Syndrome Register(ESR_EL1)
    2)中断:GIC中的寄存器(使用MMIO读取)
  • 安全性问题
    上述寄存器均不可在用户态(ELO)中访问

发生-进入EL1

  • 硬件会适当修改处理器状态(PSTATE),进入EL1执行

  • 问题:栈内存的安全性

  • 进入EL1级别后,栈指针(SP)会自动换用SP_EL1

  • 从而实现用户栈->内核栈

  • 如需在EL1下使用SP_ELO 作为栈指针,可配置SPSel寄存器。

寻找handler的代码
使用异常向量表(ExceptionVectorTable)

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

返回(Exception Return )

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

X86-64的中新和异常处理

  • 进入异常
    硬件会将上下文信息和错误码存储在内核栈上
  • 用异常向量表导找handler
    不分级
    异常向量表中存handler的地址
  • iret返回
  • 恢复程序上下文
  • 从内核态返回用户态
  • 继续执行用户程序

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.8 系统调用

系统调用(Syscall:

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

  • 系统调用提供用户程序与操作系统之间的接口

在这里插入图片描述

在这里插入图片描述

常用的系统调用

Linux追踪系统调用:

  • 每当有系统调用产生时,Linux可打印发生的系统调
    用、系统调用的参数和系统调用的返回值。

  • ptrace()可追踪Linux中的系统调用情况

  • 广泛应用在各种debugger中

  • 命令行中

  • strace追踪系统调用
    -itrace追踪库函数的调用

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
系统调用与安全

  • AArch64使用寄存器传参,个数有限
    一 如ChCore的系统调用支持使用寄存器X0-X7最多8个参数

  • 若系统调用需要更多参数如何处理?
    一 使用结构体打包参数,并将结构体的指针作为参数

问题:内存安全性
一 作为参数的指针必须经过检测!

  • 指向NULL-> kernel crash
  • 指向内核内存 --> 安全漏洞

用户指针检测

  • 完备的指针检测十分耗时
    需要遍历用户进程的所有合法内存区域进行检测;

Linux解决方法:非全面检查

  • Linux仅初步检测用户指针是否属于对应进程的用户内存区域的最大可能
    边界
    即使通过初步检测,用户指针仍然可能非法(如指向尚未分配的栈空间
    等)
    直接将非法的指针交给内核使用会导致内核出现页错误,内核态的页错
    误通常以为着bug,内核会打印异常信息并中止用户进程
    Linux采用了一些复杂机制来防止这一情况发生

处理用户指针问题

  • 内核代码仅使用特定代码片段访问用户指针(如copy_from_user)

  • 由访问用户指针而导致内核内存错误的代码段是确定的

  • 当内核发生页异常(PageFault)时,内核会检查异常发生的PC.

  • 若异常发生的PC属于访问用户指针的代码段,Linux尝试对其进行修复.

  • 若不属于,则报告问题并终止用户程序

然而
Linux中很多地方违反了这一规定,导致了许多安全漏洞。

系统调用与性能

  • 系统调用会造成大量性能开销
  • 硬件优化:新的系统调用指令
  • x86提出了syscall/sysenter/sysexit来代替int进行系统调用

软件优化
开放性问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值