分析system_call中断处理过程

姓名:王晨光

学号:20133232

王晨光  《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 

       这次实验的思路较为简单。我们在之前的 MenuOS 中加入 getpid() 功能,然后在 getpid 处打断点,然后看看这系统调用详细是怎么运作的。

一、实验步骤

实验环境是使用本课程配置的实验楼虚拟机环境,打开命令行客户端,cd LinuxKernel目录,使用命令rm -rf menu 删除原来的代码,使用git clone https://github.com/mengning/menu.git获取menu的最新代码,然后cd menu进入menu子文件夹,使用vi test.c打开文件,将上周实验的代码拷贝入test.c中,构造成两个函数,成为menu的两个菜单项。实验截图如下:

在main()函数中添加两行命令

在第一次在main函数中添加两行命令的时候,由于粗心将代码输入错了

修改后输入make rootfs编译运行。结果如下:

可以看到输入getpid时可以看到当前的pid

然后再sys_getpid上打上断点。

到最后我们发现我们无法继续跟踪调试代码,这里system_call()并不是以个普通的函数,gdb并不能在此停下。

二、分析system_call处理流程

在start_kernel函数中,trap_init函数就是完成系统调用初始化的。在trap_init()函数中,通过中断向量,将system_call函数和0x80绑定。据此,用户态代码只要执行int 0x80中断,就会由system_call函数来处理。其中查阅的关键代码如下:

#ifdef CONFIG_X86_32  
02.    set_system_trap_gate(SYSCALL_VECTOR, &system_call);  
03.    set_bit(SYSCALL_VECTOR, used_vectors);  
04.#endif  

查阅网上相关资料和视频中老师所讲,可得到如下流程图,来表现system-call的流程:

我的理解为:system_call函数通过系统调用号查找系统调用表来查找到具体的系统调用服务进程,在执行完系统调用后在执行iret之前,内核做了一系列检查是否有新的中断产生。

三、实验体会与总结

这次实验的思路很简单,但操作起来还是有些小费时,由于自己的粗心总是在输入命令或者代码时出错,不过还好,在参考了一些资料和视频后,将整个实验完成了,也对system_call的工作流程有了一定的了解。从整体过程来看,系统通过int 0x80从用户态进入内核态。在这个过程中系统先保存了中断环境,然后执行系统调用函数。通过中断向量表,将int 0x80和system_call关联起来,system_call又是通过系统调用号,将每一个系统调用和特定的系统调用服务例程关联起来。

 

posted on 2016-03-24 07:34  20133232王晨光  阅读(202)  评论(0编辑  收藏  举报

导航