简单分析system_call中断处理过程
来源:互联网 发布:linux进入用户命令 编辑:程序博客网 时间:2024/06/03 22:54
#####################################
作者:张卓
原创作品转载请注明出处:《Linux操作系统分析》MOOC课程 http://www.xuetangx.com/courses/course-v1:ustcX+USTC001+_/about
#####################################
上一篇博客我们简单分析了系统调用的执行过程,接下来我们将详细分析从system_call开始到iret结束之间的整个过程,包括system_call对应的汇编代码的工作过程。
1) gcc编译时加上-g参数,
gcc read_asm.c -o read_asm -m32 -g
2)跟踪运行
gdb read_asm
(gdb)b sys_read
(gdb)c
(gdb)n #如果这里一直按n单步执行会进入schedule函数
(gdb)b system_call #执行int 0x80 之后执行system_call对应的代码
很可惜gdb不支持system_call 里面汇编代码的调试,没办法跟踪了。
Note:gdb中的单步跟踪命令有next和step,这两个命令的区别是next遇到函数调用时,不会进入相关函数代码;step会进入相关函数。
在init/main.c文件中start_kernel函数执行下面的语句,完成初始化:
2)系统调用的工作机制
system call在系统启动过程中初始化好了之后,一旦用户执行:int 0x80.立马调到arch/x86/kernel/entry_32.S: ENTRY(system_call),开始执行。
在系统调用返回之前,有可能发生进程调度;当前进程也有可能会有进程间通讯的信号需要处理。
arch/x86/kernel/entry_32.S :
作者:张卓
原创作品转载请注明出处:《Linux操作系统分析》MOOC课程 http://www.xuetangx.com/courses/course-v1:ustcX+USTC001+_/about
#####################################
上一篇博客我们简单分析了系统调用的执行过程,接下来我们将详细分析从system_call开始到iret结束之间的整个过程,包括system_call对应的汇编代码的工作过程。
一. gdb跟踪系统调用内核函数sys_read
这里,我们还是用上一篇中用的read_asm.c,源代码此次就不重复附上了。1) gcc编译时加上-g参数,
gcc read_asm.c -o read_asm -m32 -g
2)跟踪运行
gdb read_asm
(gdb)b sys_read
(gdb)c
(gdb)n #如果这里一直按n单步执行会进入schedule函数
(gdb)b system_call #执行int 0x80 之后执行system_call对应的代码
很可惜gdb不支持system_call 里面汇编代码的调试,没办法跟踪了。
Note:gdb中的单步跟踪命令有next和step,这两个命令的区别是next遇到函数调用时,不会进入相关函数代码;step会进入相关函数。
二. 系统调用在内核代码中的处理过程
1)系统调用在内核代码中的初始化在init/main.c文件中start_kernel函数执行下面的语句,完成初始化:
trap_init();在arch/x86/kernel/traps.c中有具体的初始化步骤:
#ifdef CONFIG_X86_32set_system_trap_gate(SYSCALL_VECTOR, &system_call);set_bit(SYSCALL_VECTOR,used_vectors);#endif安装系统调用向量表,设置使能。
2)系统调用的工作机制
system call在系统启动过程中初始化好了之后,一旦用户执行:int 0x80.立马调到arch/x86/kernel/entry_32.S: ENTRY(system_call),开始执行。
在系统调用返回之前,有可能发生进程调度;当前进程也有可能会有进程间通讯的信号需要处理。
arch/x86/kernel/entry_32.S :
ENTRY(system_call)...SAVE_ALL #保存现场...syscall_call:call *sys_call_table(,%eax,4) #调用系统调用服务程序syscall_after_call:movl %eax, PT_EAX(%esp) #store the return valuesyscall_exit:...jne syscall_exit_work #进程调度时机restore_all:TRACE_IRQS_IRET...irq_return:INTERRUPT_RETURN #到这里,整个system_call 执行完毕上面的汇编代码是对entry_32.S代码的简化,仅仅只是摘录的系统调用最精要的汇编语句。其实汇编执行过程比这个还用复杂得多,为了更方便理解,进一步删减entry_32.S汇编代码,得到如下system_call 伪代码:
# asm pseudo code#系统调用处理过程的汇编伪代码.macro INTERRUPT_RETURN iret.endm.macro SAVE_ALL ....endmENTRY(system_call) SAVE_ALLsyscall_call: call *sys_call_table(,%eax,4) #执行系统调用的服务程序 movl %eax,PT_EAX(%esp) #store the return valuesyscall_exit: testl $_TIF_ALLWORK_MASK, %ecx # current->work jne syscall_exit_work #1. 有进程需要调度,2. 有信号需要处理···restore_call: RESTORE_INT_REGSirq_return: INTERRUPT_RETURN #中断返回ENDPROC(system_call)syscall_exit_work: testl $_TIF_WORK_SYSCALL_EXIT, %ecx jz work_pendingEND(syscall_exit_work)work_pending: testb $_TIF_NEED_RESCHED, %cl #判断是否需要进程调度 jz work_notifysigwork_resched: call schedule #执行进程调度 jz restore_all #返回restore_allwork_notifysig:... #deal with pending signalsEND(work_pending)根据上面的伪代码,我们可以清晰的画出从system_call 到iret之间的处理过程的流程图:
截图来自:http://www.linuxdiyf.com/linux/22253.html
三. 总结
从system call执行过程可以看出,系统调用其实也是一种中断,软中断。执行过程包括中断响应,也是就是执行系统调用服务程序,执行完毕后中断返回。但是在执行系统调用服务程序的时候,可能会发生进程调度和信号处理,使得整个system call 汇编程序变得复杂起来。但是,总体而言,执行过程:中断响应,保存现场,执行中断服务例程,恢复现场,中断退出。 0 0
- 简单分析system_call中断处理过程
- 分析system_call中断处理过程
- system_call中断处理过程分析
- system_call中断处理过程分析
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- system_call中断处理过程分析
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- 分析system_call中断处理过程
- OSG入门_场景图形与OpenSceneGraph概述02
- golang实现简易TCP服务以及TCP和UDP协议对比
- Hydra 实验学习笔记
- hibernate的核心接口
- 接上,优化滚动的效率
- 简单分析system_call中断处理过程
- java 虚拟机 参数配置
- Linux下SSH安装配置使用详解
- 小白在mac中的Python2.7及Python3.6中安装Pygame
- Android基础知识01
- 专杀工具源码 V1.5
- 名词解释
- 标题栏随RecyclerView滑动动态修改透明度
- 团体程序设计天梯赛-练习集 -- L2-018. 多项式A除以B(多项式除法--模拟)