《Linux内核分析》之分析system_call中断处理过程实验总结
前言
先占个位置,在实验楼做实验,刚做完一半忘了延续时间,结果之前写的代码神马的全没了。让我先去角落哭会,总结明天再写。2015-04-04 今天继续昨天未完工的内容,跟踪到一半发现运行结果有些奇怪,一直s了一段时间后坚持不下去了,finish了一下发现跟踪中出现问题了,最后也不知跟踪到了哪里,算了,还是直接寻找分析system_call中断处理过程吧。2015-04-05 之前代码参考地址:《Linux内核分析》之触发一个系统调用实验总结
代码与分析
跟踪截图
多图预警,由于跟踪失败,感觉仅可做个动过手的见证,但可看性不高,可以略过,具体的看个人了。明天添加干货。2015-04-05 [toggle hide=“yes” title=“跟踪截图” color=“”]
从下图开始出现各种神奇的代码
最后finish的两张图
[/toggle]
主要代码段
xref: /linux-3.18.6/arch/x86/kernel/entry_32.S的490行起(持续更新中-2014-4-7)
# system call handler stub
ENTRY(system_call)
RING0_INT_FRAME # can't unwind into user space anyway
ASM_CLAC
pushl_cfi %eax # save orig_eax
SAVE_ALL
GET_THREAD_INFO(%ebp)
# system call tracing in operation / emulation
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmpl $(NR_syscalls), %eax
jae syscall_badsys
syscall_call:
call *sys_call_table(,%eax,4)
syscall_after_call:
movl %eax,PT_EAX(%esp) # store the return value
syscall_exit:
LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
TRACE_IRQS_OFF
movl TI_flags(%ebp), %ecx
testl $_TIF_ALLWORK_MASK, %ecx # current->work
jne syscall_exit_work
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
代码分析
SYSCALL_VECTOR系统调用的终端向量,system_call汇编代码的入口 当执行int$0x80时CPU自动跳转到system_call这个位置来执行 系统调用机制一旦在start_kernel初始化好之后,即在代码中一旦出现int$0x80的指令立即跳转到system_call这个位置,其位置在xref: /linux-3.18.6/arch/x86/kernel/entry_32.S的ENTRY(system_call) SAVE_ALL保护现场 call *sys_call_table(,%eax,4) %eax传递系统调用号,此段在本实验中实际执行的是sys_fork() movl %eax,PT_EAX(%esp) 调用完之后保存返回值。 退出之前若无syscall_exit_work则restore_all:返回用户态 反之:进入syscall_exit_work,里面有个进程调度时机。
简略伪代码
部分分析在代码中注释。
ENTRY(system_call)
SAVE_ALL
syscall_call:
call *sys_call_table(,%eax,4)
movl %eax,PT_EAX(%esp) # store the return value
syscall_exit:
testl $_TIF_ALLWORK_MASK, %ecx # current->work //检测当前的任务是否需要处理syscall_exit_work
jne syscall_exit_work
restore_all:
TRACE_IRQS_IRET
irq_return:
INTERRUPT_RETURN //不需时执行restore_all和irq_return结束
ENDPROC(system_call)
//一般需要处理一些,若当前系统接收到一些信号如需要调度时,执行syscall_exit_work
syscall_exit_work:
testl $_TIF_WORK_SYSCALL_EXIT, %ecx
jz work_pending //跳转到work_pending
END(syscall_exit_work)
work_pending:
testb $_TIF_NEED_RESCHED, %cl
jz work_notifysig //处理信号
work_resched: //重新调度
call schedule
jz restore_all //调度完成跳转至restore_all(将恢复现场的工作结束掉)返回系统调用
work_notifysig:
。。。
END(work_pending)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
在系统调用返回之前可能发生进程调度(即call schedule),当前进程可能有些信号需要处理(即work_notifysig) 小白分析,代码及下面的流程图错误难免,欢迎及时指出。
总结
当一个系统调用发生时,进入内核处理系统调用,内核提供了一些服务,服务结束返回用户态之前可能会发生进程调度,进程调度里面会发生中断上下文的切换和进程上下文的切换。 内核可以抽象成是很多种不同的中断处理过程的集合,一些内核线程可当成一般的服务理解。 windCoder原创作品转载请注明出处
参考资料
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
除特别注明外,本站所有文章均为 Windcoder网 原创,转载请注明出处来自: linux-nei-he-fen-xi-zhi-fen-xi-system_call-zhong-duan-chu-li-guo-cheng-shi-yan-zong-jie

好吧,我也占个板凳。
:twisted: 看不懂 我是来占位的!