#####################################
作者:张卓
原创作品转载请注明出处:《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 value
syscall_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_RETURNiret
.endm
.macro SAVE_ALL...
.endm
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->workjne syscall_exit_work         #1. 有进程需要调度,2. 有信号需要处理···
restore_call:RESTORE_INT_REGS
irq_return:INTERRUPT_RETURN           #中断返回
ENDPROC(system_call)
syscall_exit_work:testl $_TIF_WORK_SYSCALL_EXIT, %ecxjz 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:
...                      #deal with pending signals
END(work_pending)

根据上面的伪代码,我们可以清晰的画出从system_call 到iret之间的处理过程的流程图:

截图来自:http://www.linuxdiyf.com/linux/22253.html

三. 总结

从system call执行过程可以看出,系统调用其实也是一种中断,软中断。执行过程包括中断响应,也是就是执行系统调用服务程序,执行完毕后中断返回。但是在执行系统调用服务程序的时候,可能会发生进程调度和信号处理,使得整个system call 汇编程序变得复杂起来。但是,总体而言,执行过程:中断响应,保存现场,执行中断服务例程,恢复现场,中断退出。

5. 简单分析system_call中断处理过程相关推荐

  1. 实验5 :分析system_call中断处理过程

    分析system_call中断处理过程 上周我们使用gcc内嵌汇编调用系统调用,这次我们具体分析下过程. 将getpid嵌入menuos 代码从github下载,步骤如下: 1. 增加一个函数,get ...

  2. 分析system_call中断处理过程

    分析system_call中断处理过程 上周我们使用gcc内嵌汇编调用系统调用,这次我们具体分析下过程. 将getpid嵌入menuos 代码从github下载,步骤如下: 1. 增加一个函数,get ...

  3. Linux内核设计第五周学习总结 分析system_call中断处理过程

    陈巧然原创作品 转载请注明出处   <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 使用gdb跟踪分析一 ...

  4. Linux系统调用getuid的简单分析

    陈铁 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000. Linux内核启 ...

  5. JSP 编译和运行过程与JSP源码简单分析

    JSP 编译和运行过程与JSP转移源码简单分析 Web容器处理JSP文件请求的执行过程主要包括以下4个部分: 1. 客户端发出Request请求 2. JSP Container 将JSP转译成Ser ...

  6. 从Mysql源代码角度分析一句简单sql的查询过程

    1. 前言 使用mysql这么多年,以前一直只懂写sql,却不其中运行原理,直至最近抽时间看了一下mysql源代码, 对其事务运行原理及sql解析优化有一些更深入的理解. 本篇是讲述sql解析的开篇之 ...

  7. 中断处理过程示意图_聊聊什么是中断机制?

    什么是中断 中断其实是一种"中断"事件,中断具体代表什么意思需要考虑它所处的上下文环境和参照对象是谁.考虑事件,我们可以简单把中断抽象为这样一种模型: 当我们分析某种中断事件时,我 ...

  8. x86异常处理与中断机制(3)中断处理过程

    上一节讲完了根据中断类型号找中断服务程序的过程,现在着重说明一下更加完整的中断处理过程吧. 本节以8086时代的中断处理过程为例进行说明,主要分两大部分 硬件处理 软件处理 需要注意,这不是绝对的,得 ...

  9. 中断处理过程示意图_ucore操作系统实验笔记 - Lab1

    最近一直都在跟清华大学的操作系统课程,这个课程最大的特点是有一系列可以实战的操作系统实验.这些实验总共有8个,我在这里记录实验中的一些心得和总结. Task1 这个Task主要是为了熟悉Makfile ...

最新文章

  1. python:Json模块dumps、loads、dump、load介绍
  2. debian+pxe+preseed.cfg 安装配置
  3. 控件无法安装,windows已经阻止此软件因为无法验证发行者
  4. virtualbox虚拟机XP连接本地WinXP
  5. tabbar怎么些_vue 做的tabBar组件
  6. python 使用mysqldb模块通过ssh隧道连接mysql
  7. 《Python数据挖掘:概念、方法与实践》——1.5节小结
  8. php函数内调用类的变量,php - 如何调用一个类变量的闭包?
  9. go context之WithTimeout的使用
  10. 时间复杂度和空间复杂度[数据结构]
  11. 使用Numpy和Opencv完成图像的基本数据分析(Part III)
  12. leetcode算法—无重复字符的最长子串 Longest Substring Without Repeating Characters
  13. react native多语言_前端福音:为什么使用 React 和 SVG 开发图形 UI 是天作之合?
  14. 【CCCC】L2-016 愿天下有情人都是失散多年的兄妹 (25分),,搜索公共祖先
  15. 【Verilog】组合逻辑写法
  16. MODIS数据下载——CSV模式直接下载hdf文件
  17. js 调用jsp java代码_如何在 js 代码中使用 jsp 标签或 Java 代码
  18. Swiper 参数说明
  19. 一到两年工作经验的看完这些面试轻松拿offer
  20. 腾讯im及时登录注册

热门文章

  1. jQuery炫丽星空3d旋转星空
  2. unable to connect to mks:Failed to connect to server XXXXXX:902
  3. upload-labs 1~17题
  4. 个人消费管理系统(C语言)
  5. 如何让你的简历在众多候选人的简历中脱颖而出?
  6. 两次面跪阿里,7年工作经验连个P6+都不配拥有吗?
  7. JAVA Thread.sleep实现原理
  8. 基于神经网络的中文论文评分器(Transformer + XGBoost)
  9. STM32---FLASH编程
  10. mac环境Android将屏幕录制视频转化成GIF动态图