批处理模式(操作系统)
- 作用:
当一个程序运行结束后切换到下一个程序来运行的程序 - 维护:
程序崩溃了会回到操作系统,但如果操作系统崩溃了就糟糕了,所以要将与操作系统、系统有关的函数保护起来 - 方法:
给不同程序设立等级,操作系统等级最高,可以运行系统相关的操作,用户程序等级最低,只能运行最基础的操作。当用户程序想越界操作时,cpu会先检查其等级是否合适,然后分类讨论 - 本质:
在硬件中加入一些与特权级检查相关的门电路(例如比较器电路), 如果发现了非法操作, 就会抛出一个异常信号, 让CPU跳转到一个约定好的目标位置, 并进行后续处理.
自陷操作
初始化:
- 程序(测试文件)
- 调用ioe初始化
- 调用cte初始化,在汇编代码中插入csrw指令,将异常入口地址存入mtvec中
- am(抽象的硬件,屏蔽了不同架构硬件的区别,让软件可以运行在不同架构的硬件上)
- 根据架构转化为对硬件内存的操作
- 硬件(nemu及设备):
- 对指定的内存地址进行读写操作
- 执行csrw指令,对mtvec寄存器进行读写
自陷循环
- 程序(测试文件):
- 程序调用yield(),在汇编代码中插入ecall指令
- 硬件(nemu及设备):
- ecall指令调用isa_raise_intr()函数
- isa_raise_intr()
- 将当前PC值保存到mepc寄存器
- 在mcause寄存器中设置异常号
- 从mtvec寄存器中取出异常入口地址,跳转到异常入口地址 __am_asm_trap (设置dnpc)
- 汇编程序(异常处理函数 __am_asm_trap )
1. 调用csrr将mepc、mstatus、mcause进行读出到临时寄存器
2. 调用sw将mepc、mstatus、mcause、通用寄存器等的值存入栈
1. 因为接下来的异常处理可能会修改那些值
3. 调用函数__am_irq_handle()进行异常处理
1. 根据上下文信息,判断事件
2. 将mepc+4,确保后面的能正常跳转回去
3. 调用回调函数simple_trap
1. 根据事件,做出对应的反应
4. 调用lw将mepc、mstatus、mcause的值从栈中恢复到临时寄存器
5. 调用csrw将mepc、mstatus、mcause的值从临时寄存器写入到寄存器
6. 调用mret返回,根据mepc寄存器恢复PC - 异常处理结束
- 重复1、2、3的步骤