首页 > 其他分享 >Lec 03 系统指令集架构

Lec 03 系统指令集架构

时间:2024-11-12 12:56:33浏览次数:1  
标签:03 Lec 操作系统 内核 指令集 寄存器 EL1 异常 CPU

Lec 03 系统指令集架构

(参考来源:上海交通大学并行与分布式系统研究所+操作系统课程ppt)
Creative Commons Attribution 4.0 License

Contents

3.1 回顾:特权级的必要性

  • 一台计算机上同时运行多个应用程序,如何保证不同应用间的隔离?
  1. 如果所有的应用均能完全控制硬件计算资源,则会导致混乱
    例如:某个应用希望关机,某个应用希望格式化硬盘
  2. 因此必须先让应用降权,不允许直接改变全局的系统状态
    例如:中断是否打开
  • 方案:必须要有不同的权限级——至少两种权限
  1. 低权限:不允许改变全局系统状态,用来运行应用
  2. 高权限:集中运行能改变全局系统状态的操作,形成了操作系统
  3. 特权操作:操作设备(读取文件、发送网络包…)、调整CPU频率、提供进程间通信…

alt

3.2 ARM v8.4特权级别(Exception Level)

alt

3.2.1 系统状态寄存器:PSTATE

  • 抽象进程状态信息(PSTATE)
  1. 条件码 (Condition flags)
    e.g. NZCV
  2. 执行状态 (Execution state controls)
    e.g. CurrentEL:CPU当前特权级别
  3. 异常掩码 (Exception mask bits)
    e.g. DAIF
  4. 访问控制(Access control bits)
    例如PAN(Privileged Access Never)

alt

3.2.2 用户ISA和系统ISA

  • 用户ISA
  1. 通用寄存器
  2. (用户)栈寄存器
  3. 条件码寄存器
  4. 运算指令等
  • 系统ISA
  1. 系统寄存器
  2. 系统指令

alt

3.2.3 用户态(EL0)与内核态(EL1)

  • 用户态(User-mode)
    1.只能使用用户 ISA
  • 内核态(Kernel-mode)
    2.可以同时使用系统 ISA 和用户ISA
  • 操作系统往往同时包含内核态与用户态的代码
    3.如:Unix包含内核态的kernel 与 用户态的 shell
  • aarch64中常见寄存器在不同特权级中的可见情况:

alt

3.3 特权级切换(EL0与EL1)

3.3.1 用户态与内核态之间的控制流跳转

  • 初始时CPU处于用户态(EL0)执行应用程序,如何改变CPU控制流从用户态进入内核态?
  1. 已知的两种改变控制流的方式:
    (1) 跳转指令,如 b
    (2) 过程调用与返回指令,如 bl 和 ret
  2. 这两种方式只能在同一种模式之间跳转
  3. 需要新的指令(在控制流跳转的同时进行特权级切换):
    例如:svceret

3.3.2 进行特权级切换的必要性

  • 操作系统的职责之一:
  1. 服务应用、管理应用
  • 特权级切换的必要性:
  1. 将CPU控制权移交给内核
  2. 服务:应用程序向操作系统请求服务
  3. 管理:操作系统能够切换不同应用程序执行
    否则,错误/恶意程序死循环怎么办(操作系统终止恶意程序(故意/无意))

3.3.3 异常处理特权级切换

  • 同步异常: 执行当前指令触发异常
  1. 第一类:用户程序主动发起:svc指令(OS利用eret指令返回)
  2. 第二类:非主动,例如用户程序意外访问空指针:普通ldr指令(OS“杀死”出错程序)
  • 异步异常: CPU收到中断信号
  1. 从外设发来的中断,例如屏幕点击、鼠标、收到网络包
  2. CPU时钟中断,例如定时器超时

alt

OS处理完异常后一定返回到被打断执行的用户程序吗?
不一定。原因如下。

3.3.4 异常处理函数

  • 异常处理函数属于操作系统的一部分
  1. 运行在内核态的代码
  • 异常处理函数完成异常处理后,将通过下述操作之一转移控制权:
  1. 回到发生异常时正在执行的指令
  2. 回到发生异常时的下一条指令
  3. 切换到其它进程执行

3.3.5 CPU寻找异常处理函数:异常向量表

  • 操作系统内核预先在一张表中准备好不同类型异常的处理函数
  1. 基地址存储在VBAR_EL1寄存器中
  2. 系统寄存器
  • CPU在异常发生时自动跳转到相应处理函数
  1. 同步异常:主动下陷svc、指令执行出错
  2. 异步异常:中断(IRQ、FIQ)、SError

alt

3.3.6 CPU执行逻辑

  • CPU的执行逻辑很简单
  1. 以PC的值为地址从内存中获取一条指令并执行
  2. PC+=4,goto 1(简化,表示跳转/函数调用)
  • 执行过程中可能发生两种情况
  1. 指令执行出现异常,比如svc、缺页(同步异常)
  2. 外部设备触发中断(异步异常)
  • 这两种情况在ARM平台均称为「异常」
  1. 均会导致CPU陷入内核态,并根据异常向量表找到对应的处理函数执行
  2. 处理函数执行完后,执行流需要恢复到之前被打断的地方继续运行

3.3.7 操作系统关于异常处理的任务

一、实现对异常向量表的设置

  1. 该设置是系统初始化的重要工作之一:在开启中断和启动第一个应用之前
  2. msr vbar_el1, x0 (是内核态才能使用的指令,内核才能访问的寄存器)

二、实现对不同异常(中断)的处理函数

  1. 处理应用程序出错的情况:如访问空指针
    Q:内核如果自己运行出错怎么办?
    A:同样内核异常处理,但无需下陷(已经处于内核态)。有些平台在三次递归后会抛出triple-fault
  2. 一类特殊的同步异常:系统调用,由应用主动触发
    Q:内核如何识别出是系统调用(而不是其他异常)?
    A:执行mrs x1, esr_el1,内核通过 ESR_EL1 寄存器读取陷入内核的原因
  3. 处理来自外部设备的中断:如收取网络包、获取键盘输入等

alt

3.4 用户态和内核态的切换

3.4.1 处理器状态变化

alt

3.4.2 处理器的任务

  1. 将发生异常事件的指令地址保存在ELR_EL1中
  2. 将异常事件的原因保存在ESR_EL1
    例如,是执行svc指令导致的,还是访存缺页导致的
  3. 将处理器的当前状态(即PSTATE)保存在SPSR_EL1
  4. 栈寄存器不再使用SP_EL0(用户态栈寄存器),开始使用SP_EL1
    内核态栈寄存器,需要由操作系统提前设置
  5. 修改PSTATE寄存器中的特权级标志位,设置为内核态
  6. 找到异常处理函数的入口地址,并将该地址写入PC,开始运行操作系统
    根据VBAR_EL1寄存器保存的异常向量表基地址,以及发生异常事件的类型确定

为什么操作系统不能直接使用应用程序在用户态的栈呢?

  • 安全问题。当操作系统的栈和用户态程序栈混合时,会使得操作系统的栈被用户态程序访问,导致内核级操作可以被应用操作。

处理器的这些操作都是必要的么?

  1. PC寄存器的值必须由处理器保存
    否则当操作系统开始执行时,PC将被覆盖
  2. 栈的切换也必须由硬件完成
    否则操作系统有可能使用用户态的栈,导致安全问题

3.4.3 eret:从内核态返回到用户态

  1. 将SPSR_EL1中的处理器状态写入PSTATE中
    处理器状态也从 EL1 切换到 EL0
  2. 栈寄存器不再使用SP_EL1,开始使用SP_EL0
    注意:SP_EL1的值并没有改变
    下一次下陷时,操作系统依然会使用这个内核栈
  3. 将ELR_EL1中的地址写入PC,并执行应用程序代码

3.4.4 操作系统在切换过程中的任务

  1. 主要任务:将属于应用程序的 CPU 状态保存到内存中
    用于之后恢复应用程序继续运行
  2. 应用程序需要保存的运行状态称为处理器上下文
    (1) 处理器上下文(Processor Context):应用程序在完成切换后恢复执行所需的最小处理器状态集合
    (2) 处理器上下文中的寄存器具体包括:
    1.通用寄存器 X0-X30
    2.特殊寄存器,主要包括PC、SP和PSTATE
    3.系统寄存器,包括页表基地址寄存器等

标签:03,Lec,操作系统,内核,指令集,寄存器,EL1,异常,CPU
From: https://www.cnblogs.com/mumujun12345/p/18541603

相关文章

  • lec 02 arm汇编语言基础
    Lecture02:ARM汇编基础Contents为什么学习ARM/ISA汇编从C到汇编理解arm汇编理解机器执行1为什么学习汇编和指令集架构?1.令人困惑的应用表现2.指令集架构ISA(InstructionSetArchitecture)CPU向软件(应用程序和操作系统)提供的接口。理解软件在CPU上的运行(OS设......
  • 代码随想录算法训练营第三天(LeetCode203.移除链表元素;LeetCode707.设计链表;LeetCode20
    LeetCode203.移除链表元素题目链接:LeetCode203.移除链表元素题目链接思路这道题目主要考察的是移除一个链表当中的元素,我们可以先在给定的链表前面加一个虚拟头结点,这样我们对给定链表头结点的操作和给定链表其余结点的操作就会变得相同。代码classSolution{p......
  • 介绍Go中的for select case和chan 和goroutine
    好的,让我们详细分析您提供的代码片段:for{select{casemsg:=<-sensorChan://处理消息的代码}}1.整体结构概述这段代码使用了Go语言的并发控制结构,结合无限循环(for)、选择语句(select)、以及case分支来处理从sensorChan通道接收......
  • 模态内重叠优化,简单有效的CLIP微调方法 | BMVC'24 Oral
    来源:晓飞的算法工程笔记公众号,转载请注明出处论文:CLIPAdaptationbyIntra-modalOverlapReduction论文地址:https://arxiv.org/abs/2409.11338创新点提出一种基于轻量级适配的新方法,直接在图像空间中减少CLIP中的模态内重叠(IMO)。新特征与任何利用缓存模型的无训练......
  • 洛谷题单103数组题解||by红糖
    P1428小鱼比可爱题目描述人比人,气死人;鱼比鱼,难死鱼。小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度。参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然整数越大,表示这只鱼越可爱,而且任意两只鱼的可爱程度可能一样......
  • P8162 [JOI 2022 Final] 让我们赢得选举 (Let's Win the Election) 题解
    P8162[JOI2022Final]让我们赢得选举(Let'sWintheElection)题解朴素的想法是先抓一部分人,再一起去发表演讲。这样就要按\(b\)的值从小到大排序,枚举选择的一部分\(b\)值,在后面挑选一些最小的\(a\)选择即可。但这样显然是错误的。观察到\(n\le500\),显然是\(O(n^3......
  • 【Azure Developer】在使用Azure Bot Service JavaScript的实例代码遇见Cannot find m
    问题描述从Github中下载了JavaScript的BotServiceEchoBot实例代码,本地执行,总是报错Cannotfindmodule'node:crypto' 错误信息Error:Cannotfindmodule'node:crypto'Requirestack:atFunction.Module._resolveFilename(internal/modules/cjs/loader.js:902:15)......
  • springboot033小徐影城管理系统
    ......
  • 2028E - Alice's Adventures in the Rabbit Hole
    可以先从一条链的情况开始观察,然后发现每次都会选深度最小的子节点(minf(v)),可以看作一个短链剖分,不过我不是这么写的g(v)表示的是f(v)是f(u)的几分之几我推的式子是这两个,但是我没法证明g(v)不会等于2使得分母为0但是我觉得因为g(x)一定是合法的所以显然2-g(v)不会为0\(f(x)=\frac......
  • springboot项目使用JpaRepository后启动报错A component required a bean named 'XXX'
    在最近的项目中我使用了JpaRepository作为数据处理的接口,但在调用接口时始终报错,经过查询后发现问题出在导入的包不对,我导入的包为org.springframework.dataspring-data-jpa2.6.9应该导入的包为org.springframework.bootspring-boot-starter-data-jpa2.6.9spring-dat......