分析system_call中断处理过程
20125119
尹颢澎《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
这次的实验是 使用gdb跟踪分析一个系统调用内核函数,本次实验用的是122号函数uname。
一、在实验楼的虚拟机中MenuOs增加utsname指令。
具体实现如下:
1、克隆 新版本的menu并进入menu
2、进入test.c
3、添加相应代码
4、完成之后make rootfs,使系统自动编译自动运行
5、执行help指令,这时可发现menu支持的命令增加了utsname指令
二、开始使用gdb追踪系统调用内核函数sys_time(此部分截图来源于课程视频)
1、设置断点sys_time,继续执行,系统会启动到menuos
2、执行time命令
3、此时一直按s单步执行会进入get_seconds函数
4、执行完毕
5、再一直按s单步执行到returni
6、继续单步执行到特殊代码,无法跟踪
7、设置断点(system_call),继续执行可发现time有返回
8、执行time-asm(发现不能在system_call处停下)
然后找到system_call函数(可发现它只是一段汇编代码的起点,gdb无法进行识别调试)
三、分析system_call代码的具体调用过程( 代码在kernel/entry_32.S中)
简化代码如下:
代码中先定义了两个宏(SAVE_ALL、RESTORE_ALL)
分析过程如下:
16行是调用此系统调用所对应的函数(在122号函数uname中调用的就是sys_newuname);
17行保存返回值;
在18行exit的时候,会检测当前的任务是不是需要处理;
如果不需要处理,就跳转到21行restore_all;
然后执行23行return,系统调用就结束了。
***但是一般情况下都会有需要处理的任务,此时就会进入到26行处 syscall_exit_work
然后跳转到30行work_pending, 32行处理信号;
如果需要重新调度,就会执行到33行work_resched,先进行调度call_schedule,然后再跳转到restore_all,返回系统调用。
四、实验总结:
在系统调用返回之前,其中可能还会发生中断上下文的切换和进程上下文的切换,也可能会发生进程调度;
在当前进程的时候,有些信号可能需要处理。
内核可以抽象成是很多种不同的中断处理过程的集合。