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

实验步骤

工具下载、源码下载和相关配置已在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负责保存现场的代码相对应。

猜你喜欢

转载自blog.csdn.net/weixin_43363720/article/details/130695122