syscall 系统调用陷入_MIPS中的异常处理和系统调用【转】-阿里云开发者社区

本文详细介绍了MIPS架构中系统调用的处理流程,包括异常入口、异常处理函数、系统调用表以及异常处理的步骤。在异常发生时,CPU会设置EPC和Status寄存器,然后跳转到异常处理程序。系统调用通过异常类型ExcCode定位到处理函数,并在内核中执行相应任务。系统调用表存储了所有系统调用的处理函数地址,根据系统调用号执行不同的操作。异常处理函数通过读取Cause寄存器并跳转到处理函数地址执行。在系统调用完成后,会恢复现场并返回用户态。
摘要由CSDN通过智能技术生成

异常入口

系统调用是用户态和内核态通信的一种方式,用户程序可以直接调用系统调用的接口陷入内核中执行相关任务,完成后返回用户态继续运行。

应用程序使用系统调用很简单,直接调用C库提供的系统调用接口即可。在C库中,对用户传入的参数进行分析和保存,然后通过syscall指令引发系统调用异常,之后便陷入内核。

内核处理根据系统调用号执行相应的处理函数,并将结果返回到用户态。

图1 系统调用大体流程

当发生异常时,协处理器0的Cause寄存器会记录发生了什么种类的异常。Cause寄存器的每个域如图2所示。其中bit6-2(ExcCode)位中保存了具体发生了什么异常,系统可以根据异常种类决定调用哪一个异常处理例程。

图2 Cause寄存器

所有的异常入口都位于mips内存映射中不需要地址转换的区域——非缓存的kseg1段和缓存的kseg0段。如图3所示,RAM中的异常入口点的起始地址为BASE+0x000,BASE表示EBase寄存器编程的异常基地址。一些特殊的异常的处理例程有单独的地址存放其异常处理例程,如缓存异常和TLB重填等,其他异常处理例程都放在BASE+0x180地址处。

图3 异常处理入口

BASE+0x180共存放了32种异常的入口函数地址,图4中显示了部分异常类型对应的ExcCode值,可以看到其中系统调用对应的ExcCode等于8。当发生系统调用时,内核就可以根据Cause寄存器查看异常类型,然后跳转到BASE+0x180地址处执行,执行的结果就是找到对应的处理函数并跳转到处理函数的地址去执行。

图4 异常类型

这些异常处理函数的注册在trap_init()函数中完成,该函数将上面所说的32个异常的处理函数地址放到一个全局数组exception_handlers中,这个全局变量定义为:

unsigned long exception_handlers[32];

这个全局变量是unsigned long型,每个元素的值就是一种异常向量处理函数的入口地址。

那BASE+0x180地址处的代码如何找到异常对应的处理函数呢。trap_init()函数中将except_vec3_generic拷贝到了BASE+0x180,这是一个函数,其实现如下:

NESTED(except_vec3_generic, 0, sp)

.set push

.set noat

mfc0 k1, CP0_CAUSE #读取协处理器0的cause寄存器保存到k1中。

andi k1, k1, 0x7c #取得k1的2-6位,即excCode

#取得exception_handlers[excCode]的值

PTR_L k0, exception_handlers(k1)

jr k0 #跳转到excCode对应的处理函数去执行

.set pop

END(except_vec3_generic)

由except_vec3_generic的实现可知,它负责读取Cause寄存器并跳转到异常处理函数。

产生异常时,MIPS CPU所要做的主要工作为:

设置EPC,指向异常返回的位置。

置Status寄存器的EXL位,迫使CPU进入内核模式(高特权级)并且禁用中断。

设置Cause寄存器,使得软件可以看到异常的原因。

CPU从异常处理入口点取指执行,即执行异常处理程序。

异常处理的流程主要包括以下步骤:

保护现场,将各个寄存器的值压栈,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值