MOOC《Linux内核分析》——分析system_call中断处理过程
2015-04-05 20:17
633 查看
许松原创,转载请注明出处。
《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000
上一节课程展示了如何用库函数API和C内嵌汇编代码完成同一个系统调用,本次将会在其基础上对system_call中断处理过程进行分析。
准备工作:
首先根据视频指导将上次的系统调用集成到MenuOS中,并额外添加ls命令(这里不再提供代码,参考上篇博文以及课程指导可以很容易做出):
红框中为创建文件夹之前根目录的文件列表,蓝框部分执行创建命令,绿框部分则是结果,可以看到命令顺利集成到MenuOS中了。
分析system_call:
在对start_kernel的分析时,我们曾经看到过他所调用的个函数:trap_init()。这个函数位于x86/kernel/traps.c第792行,在这个函数中,我们第一次看到了system_call,位于第834行的宏之中:
这里的SYSTEMCALL_VECTOR经过跟踪之后发现其位于/x86/include/asm/irq_vectors.h中,这里我们发现了熟悉的0x80:
可以看到这里把0x80与system_call关联起来了,上一课中的结论在这里得到了印证。而set_bit则是将对应的系统调用映射表给填装完成了。当系统运行时,如果有程序通过int 0x80使得程序陷入态,那么将会通过ENTRY(system_call)(在第490行)进行API的调用工作,这个工作直到第588行的ENDPROC(system_call)结束。下面我们将着重分析这个过程中的一些关键步骤(下面代码进行了简化,只保留了我们需要关注的部分)。
下面给出流程图以供参考,个人认知有限,不能给出精确的流程,还望见谅。
《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000
上一节课程展示了如何用库函数API和C内嵌汇编代码完成同一个系统调用,本次将会在其基础上对system_call中断处理过程进行分析。
准备工作:
首先根据视频指导将上次的系统调用集成到MenuOS中,并额外添加ls命令(这里不再提供代码,参考上篇博文以及课程指导可以很容易做出):
红框中为创建文件夹之前根目录的文件列表,蓝框部分执行创建命令,绿框部分则是结果,可以看到命令顺利集成到MenuOS中了。
分析system_call:
在对start_kernel的分析时,我们曾经看到过他所调用的个函数:trap_init()。这个函数位于x86/kernel/traps.c第792行,在这个函数中,我们第一次看到了system_call,位于第834行的宏之中:
#ifdef CONFIG_X86_32 set_system_trap_gate(SYSCALL_VECTOR, &system_call); set_bit(SYSCALL_VECTOR, used_vectors); #endif
这里的SYSTEMCALL_VECTOR经过跟踪之后发现其位于/x86/include/asm/irq_vectors.h中,这里我们发现了熟悉的0x80:
#ifdef CONFIG_X86_32 define SYSCALL_VECTOR 0x80
可以看到这里把0x80与system_call关联起来了,上一课中的结论在这里得到了印证。而set_bit则是将对应的系统调用映射表给填装完成了。当系统运行时,如果有程序通过int 0x80使得程序陷入态,那么将会通过ENTRY(system_call)(在第490行)进行API的调用工作,这个工作直到第588行的ENDPROC(system_call)结束。下面我们将着重分析这个过程中的一些关键步骤(下面代码进行了简化,只保留了我们需要关注的部分)。
ENTRY(system_call) SAVE_ALL //保存中断上下文 testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) jnz syscall_trace_entry #根据相与的结果来判断是否转入 syscall_trace_entry cmpl $(NR_syscalls), %eax #比较传入的调用号是否合法,NR_syscalls在asm/unistd.h中第14行定义系统调用表长度 jae syscall_badsys//不合法跳转到错误处理 syscall_call: call *sys_call_table(,%eax,4)#系统调用表项是以32位存放的,所以调用号乘以4得到调用地址并调用 syscall_after_call: movl %eax,PT_EAX(%esp) # store the return value #调用返回值存到eax中 syscall_exit: DISABLE_INTERRUPTS(CLBR_ANY) #关中断 testl $_TIF_ALLWORK_MASK, %ecx # current->work jne syscall_exit_work #根据与的结果决定是否跳转到退出 restore_all: TRACE_IRQS_IRET #恢复上下文并回到用户态 irq_return: INTERRUPT_RETURN #中断返回 ENDPROC(system_call) syscall_badsys: #将调用错误值存放到eax中,然后通过syscall_after_call返回 movl $-ENOSYS,%eax jmp syscall_after_call END(syscall_badsys) syscall_trace_entry: #创建系统调用跟踪实体并继续后续步骤 movl $-ENOSYS,PT_EAX(%esp) movl %esp, %eax call syscall_trace_enter cmpl $(NR_syscalls), %eax jnae syscall_call jmp syscall_exit END(syscall_trace_entry) syscall_exit_work: testl $_TIF_WORK_SYSCALL_EXIT, %ecx jz work_pending #如果有进程调度需要执行,就转到对应位置 TRACE_IRQS_ON jmp resume_userspace #恢复到用户态 END(syscall_exit_work) work_pending: testb $_TIF_NEED_ESSCHED, %c1 jz work_notifysig #处理进程信号 work_resched: #重新调度 call schedule # 执行调度 jz restore_all work_notifysig: cmpb %USER_RPL,%bl jb resume_kernel call do_notify_resume jmp resume_userspace #回到用户态 END(work_pending)
下面给出流程图以供参考,个人认知有限,不能给出精确的流程,还望见谅。
相关文章推荐
- linux内核分析作业5:分析system_call中断处理过程
- MOOC-Linux内核lab5 分析system_call中断处理过程
- Linux内核分析(实验五)分析system_call中断处理过程
- 第5节 分析system_call中断处理过程【Linux内核分析】
- Linux内核分析实验五—分析system_call中断处理过程
- [网易云课堂]Linux内核分析(五)—— 分析system_call中断处理过程
- Linux内核分析之简析system_call中断处理过程
- Linux内核分析:分析system_call中断处理过程
- Linux内核分析学习笔记:system_call中断处理过程
- Linux内核分析——分析system_call中断处理过程
- Linux内核分析第五周学习总结——分析system_call中断处理过程
- linux内核分析第五周-分析system_call中断处理过程
- Linux内核设计第五周学习总结 分析system_call中断处理过程
- Linux内核分析-分析system_call中断处理过程
- 《Linux内核分析》第五周:分析system_call中断处理过程
- 分析system_call中断处理过程
- Linux 第五周 实验: 分析system_call中断处理过程
- system_call中断处理过程分析
- 分析system_call中断处理过程
- 分析system_call中断处理过程