lab4:以time/gettimeofday系统调用为例分析ARM64 Linux 5.4.34

文章详细介绍了ARM64架构下,从VSCode启动调试,设置断点到系统调用的处理过程。关键步骤包括el0_sync、kernel_entry0的现场保存,el0_svc的系统调用处理,以及__invoke_syscall如何执行系统调用内核函数。文章还阐述了中断向量表的工作机制,以及kernel_exit0如何恢复现场,通过eret指令从内核态返回用户态的过程。
摘要由CSDN通过智能技术生成

实验步骤

工具下载、源码下载和相关配置已在lab3中完成,现只给出关键步骤:

1、在 VSCode 中启动调试

新增断点 __arm64_sys_gettimeofday:

在这里插入图片描述

分析调用的堆栈顺序:

在这里插入图片描述

在arch/arm64/kernel/entry.S中找到el0_sync:

在这里插入图片描述

kernel_entry0保存现场:

在这里插入图片描述

el0_svc 中主要负责调用C代码的 el0_svc_handler 处理系统调用和 ret_to_user 系统调用返回。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

从invoke_syscall函数中可以看到当系统调用号(scno)小于系统调用总个数(sc_nr)时,会找到系统调用号作为下标的syscall_table数组中的函数指针(syscall_fn)。__invoke_syscall函数执行该系统调用内核处理函数,将__invoke_syscall函数的两个参数regs和syscall_fn变为调用syscall_fn(regs),regs中存储着系统调用参数(regs->regs[0-5])和系统调用号(regs->regs[8]),从而执行该系统调用内核处理函数。最后将系统系统调用内核处理函数的返回值保存到内核堆栈里保存x0的位置,以便将返回值在恢复现场系统调用返回时可以传递到用户态x0寄存器。

中断向量表根据系统调用号调用相应的内核处理函数:

在这里插入图片描述
执行完成,退栈执行后续代码,到b ret_to_user返回系统调用。

在这里插入图片描述

可以看到ret_to_user的最后是kernel_exit 0负责恢复现场,与保存现场kernel_entry 0相对应,kernel_exit 0的最后会执行eret指令系统调用返回。eret指令所做的工作与svc指令相对应,eret指令会将ELR_EL1寄存器里值恢复到程序指针寄存器PC中,把SPSR_EL1寄存器里的值恢复到PSTATE处理器状态中,同时会从内核态转换到用户态,在用户态堆栈栈顶指针sp代表的是sp_el0寄存器。

在这里插入图片描述
kernel_exit 0负责恢复现场的代码和kernel_entry 0负责保存现场的代码相对应。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值