系统调用system_call的处理过程

来源:互联网 发布:荣新it培训 编辑:程序博客网 时间:2024/05/23 13:24

关于system_call,虽然它有函数申明,但它其实是关于系统调用的一段汇编代码的起点,所以使用gdb无法跟踪到它。

下面我们通过实验来了解system_call的处理过程,首先我们需要用一个新的内核,然后把我们的系统调用函数加载进去:

          

   


然后使用make rootfs重新编译一下,就能看到新加载进去的系统调用了,



接下来我们开始追踪系统调用的过程,首先用指令b sys_getpid处设置断点,然后运行,等系统初始化完毕后,我们输入指令getpid就会发现系统会停留在Show process ID而不在运行下去,


然后按C接着运行,我们就能看到系统调用的返回值了,再使用指令getpid-asm,我们可以看到系统依旧没有返回值,直到按C继续运行,系统调用才又有返回值。


接下来我们尝试着在system_call处设置断点,gdb是可以找到这个断点的,但是由于system_call处是一段特殊的汇编代码,gdb又不支持汇编代码,所以产生的结果就是无法继续跟踪下去,


接下来再简单的分析下系统调用过程的代码:

从上面这个函数我们可以看到,系统调用是通过syscall_vecor,即中断向量与指令int $0x80匹配起来的,而&system_call是指向系统调用那段汇编代码的入口。下面是关于系统调用的一段代码,

从这段代码我们可以看到系统调用时,首先通过save_all来保存现场,然后进行系统调用,并将返回值放入寄存器eax中,然后确认有没有其他的中断进入,以便设置返回信号。如果没有就从系统调用返回,并通过函数restore_all恢复现场;如果有就进入函数syscall_exit_work,查看有没有挂起的任务,有就转入函数work_pending进行任务调度,没有就返回,并恢复现场。


实验总结:

关于系统调用的处理过程,我大致总结了下,具体流程如下:


系统调用首先需要通过中断向量与指令int $0x80匹配起来进入到内核态,再由内核态中以system_call为起点的一段汇编代码进行系统调用,其中需要用到系统调用号,然后进入系统调用函数sys_xyz(),系统调用完成后会查看有无其他挂起的任务,有就转入syscall_exit_work,没有就返回系统调用。

 作者:叶涛

 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000



0 0
原创粉丝点击