Linux编程入门(12)-理解系统调用过程

Linux编程入门(12)-理解系统调用过程,第1张

Linux编程入门(12)-理解系统调用过程

Linux 提供了具有良好定义、数量有限、直接进入内核的入口点,这些入口点被称为系统调用。

前面的文章学习了 Linux 文件以及文件系统 *** 作的基础知识,并介绍了一些系统调用函数。那么应用程序在调用系统函数时,内核的处理流程是怎样的呢?

在 Linux 系统中,分为用户空间和内核空间。从系统安全和稳定方面考虑,用户空间的程序不能直接执行内核代码或者 *** 作内核数据。但是,内核以 API 的形式,提供了一系列服务供应用程序访问,是为了从内核获得某项服务或资源。

系统调用过程

从编程角度来说,系统调用与 C 语言函数的调用很相似。然而,在执行系统调用时,会历经许多处理步骤:

  • 应用程序调用系统函数 API,发起系统调用。
  • API 将系统调用参数传入到特定寄存器。
  • API 将系统调用编号负值到一个特殊的 CPU 寄存器(%eax)中。
  • API 执行一条中断指令(int 0x80),引发处理器从用户态切换到内核态。并执行系统中断 0x80 的中断向量所指向的代码。
  • 响应中断 0x80,内核调用 system_calll() 代码来处理这次中断。
  • system_call() 调用相应的系统调用服务例程。
  • 内核态代码执行完成后,处理器切换回用户态。
  • 若系统调用服务例程的返回值有错误,API 会使用该值设置全局变量 errno。
  • API 返回到调用程序,并返回一个整型值,表示系统调用是否成功。
system_call() 处理流程

可以把 system_call() 认为是中断 0x80 的服务例程,作为内核处理系统的入口函数。其内部的处理流程有以下几步:

  • 在内核中保存寄存器值。
  • 检测系统调用编号的有效性。
  • 搜索存放系统服务例程的列表(sys_call_table),找到与系统调用编号匹配的系统调用服务例程。
  • 如果系统调用服务例程带有参数,则检测参数的有效性。然后执行系统调用函数。
  • 系统调用处理结束后,会将结果返回给 system_call()。
  • 从内核栈中恢复各个寄存器值,将系统调用返回值置于栈中。
  • 返回应用程序调用的 API,同时将处理器切换回用户态。
处理流程图

上面说了这么多,用图片表示一下更为直观。以系统调用 execve() 为例,看一下处理流程。


关注公众号【一起学嵌入式】,获取更多精彩内容

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5681623.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存