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

        

        Linux内核启动后,接管系统控制权。本质上操作系统负责资源管控,用户程序要使用任何资源,都需要申请相应的资源。系统调用就是操作系统为用户态进程与硬件设备进行交互提供的一组接口。系统调用通过软中断向内核发出一个明确的请求,使用一个封装例程完成相应的功能,将结果返回给用户进程。


    当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数。 在Linux中是通过执行int $0x80来执行系统调用的,这条汇编指令产生向量为128的编程异常。内核实现了很多不同的系统调用,进程指明需要哪个系统调用,把系统调用号作参数传入eax寄存器。下面以linux系统调用getuid为例简单分析一下系统调用过程。

//getuid.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char const *agrv[])
{
    uid_t uid;
    uid=getuid();
    printf("The current user ID:%d\n",uid);

    return 0;
}

执行结果:

wKiom1UU_3ixtkoTAANZZK1WxP4248.jpg

利用内联汇编的方式把系统调用展示一下,结果如图:


wKiom1UU_9SghojLAALk7aqDiJA811.jpg

可以看到,系统调用执行了内核的封装例程,用户进程只需要把相应的调用号放入eax寄存器,内核就在内核态完成相应的计算,把用户所要求的结果返给用户进程,参与其他运算。


    总结,我认为系统调用就是内核将常用的用户需要使用底层硬件或特权级操作的相关代码,封装成服务例程,给每个例程一个编号(系统调用号),当用户需要执行相应功能时,进程产生软中断int 0X80,装系统调用号作为参数传入eax寄存器。完成相应的功能。