Linux内核分析之系统调用工作机制简析

来源:互联网 发布:js 用法 编辑:程序博客网 时间:2024/06/05 22:08

SA16225055冯金明

原创作品转载请注明出处 

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

实验相关内容

      实验要求:

  1. 选择一个系统调用(13号系统调用time除外)
  2. 参考视频中的方式使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

实验代码以及相关截图

        选用的系统调用为getpid(获取进程标识符),系统调用号为20。选择getpid的主要原因是,它相对来说比较简单,书写它的汇编代码也不是很麻烦,而且有可以参考的实例,出现问题的话也相对容易解决。
      实现getpid系统调用的C代码截图,如下所示:


          编译执行,查看执行结果,如下图所示:

          C代码中嵌入汇编代码来实现getpid系统调用,相关代码如下图所示:

          编译执行,查看执行结果,如下图所示:

           实验当中,C语言代码整体的难度并不高,主要是对汇编代码的相关了解以及其背后的工作原理,下面将着重对汇编代码进行详细解读。

        汇编代码分析

           "mov $0x14,  %%eax\n\t"/*0x14转化为10进制为20,将20传值给eax,20是getpid的系统调用号*/

       "int $0x80\n\t"  /*执行系统调用,中断号为0x80,实现了用户态到内核态的切换*/

       "mov %%eax, %0\n\t"  /*把系统调用之后的返回值(此返回值自动存放在寄存器eax中)放入到参数pid中*/

       :"=m"(pid)    /*"="表示操作数在指令中是只写的,"m"表示内存变量,这条指令表示将pid的值写入到内存中,而不是寄存器中*/

简析系统调用

      首先,我们需要知道CPU有几种不同的指令执行级别。在Linux系统环境下,只有两种级别:0级代表内核态,3级代表用户态。中断处理是用户态进入内核态的主要方式,而系统调用则是一种特殊的中断。系统调用是:操作系统为用户态进程于硬件设备进行交互提供的一组接口!

      说道系统调用,就必须说说API(application program interface应用编程接口)。我们需要清楚二者之间的联系:

      API只是一个函数定义

       系统调用则是通过软中断向内核发出的一个明确的请求

       Libc库定义了一些API引用的封装例程,而一般每一个系统调用对应封装了一个例程,库再用这些封装例程来定义给出用户的API

       理解系统调用的三层皮:xyz(API),system_call(中断向量),sys_xyz(中断服务程序)

      以老师课堂上的那张图为例进行解析:


        我的理解是这样的:用户编写程序,调用API,API中包含着封装例程,而封装例程对应着系统调用(通过执行int $0x80来执行系统调用 )。当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数。在用户态时,系统调用号就已经存放在了eax中了,内核态中,系统可以根据这个系统调用号寻找到相应的中断服务程序,并执行之。执行完后,会通过相应的寄存器将执行结果返回(例如实验中的getpid保存至eax中),再之就是退出系统调用,退出内核态,返回用户态,接着运行源程序。

     小弟之拙见,如有什么理解错误之处,还请指点出来。老实说,老铁,这回可以给我个5分嘛!!!







0 0
原创粉丝点击