系统调用及系统调用过程

系统调用基本概念

操作系统为用户态运行的进程与硬件设备之间进行交互提供了一组接口,这组接口就是所谓的系统调用。

为什么要有系统调用?

1.通过接口屏蔽实现细节达到开箱即用的效果,把用户从学习硬件设备的低级编程特性中解放出来

2.提高了系统的安全性,可以让用户按照设计的接口进行操作,而不会因为随意的操作导致系统崩溃(类似于面向对象的封装,隐藏具体实现细节,提供接口给用户使用)

 系统调用和库函数的关系

库函数用于提供用户态服务。它可能调用封装了一个或几个不同的系统调用(printf调用write),也可能直接提供用户态服务(atoi不调用任何系统调用)。

我们可以通过库函数间接调用系统调用也可以直接使用系统调用

  • 常见系统调用
    open, close, read, write, ioctl,fork,clone,exit,getpid,access,chdir,chmod,stat,brk,mmap等,需要包含unistd.h等头文件。
  • 常见库函数
    printf,scanf,fopen,fclose,fgetc,fgets,fprintf,fsacnf,fputc,calloc,free,malloc,realloc,strcat,strchr,strcmp,strcpy,strlen,strstr等,需要包含stdio.h,string.h,alloc.h,stdlib.h等头文件。

系统调用的过程

系统调用实质上就是函数调用,只不过调用的是系统函数,处于内核态而已。 用户在调用系统调用时会向内核传递一个系统调用号,然后系统调用处理程序通过此号从系统调用表中找到相应的内核函数执行,最后返回

相关知识

现代操作系统通常让代码运行在两种不同特权的模式下
——用户态和内核态——以限制他们的权力。系统调用要操作一些有限的资源,无疑是运行在内核态的。那么用户态程序如何运行内核态的代码呢?操作系统一般是通过中断来从用户态切换到内核态。

中断

中断是指一个硬件或软件发出的请求(电信号),要求CPU暂停当前的工作转手去处理更加重要的事情。

中断有两个重要的属性,中断号中断处理程序。中断号用来标识不同的中断,不同的中断具有不同的中断处理程序。在操作系统内核中维护着一个中断向量表,这个数组存储了所有中断处理程序的地址,而中断号就是相应中断在中断向量表中的偏移量。

系统调用号

 Linux系统有几百个系统调用,为了唯一的标识每一个系统调用,Linux为每一个系统调用定义了一个唯一的编号,这个编号就是系统调用号。(在我的电脑上,它是在 /usr/include/x86_64-linux-gnu/asm/unistd_32.h, 可以通过 find / -name unistd_32.h -print 查找)。

系统调用号的目的是作为系统调用表的下标,当用户空间的进程执行一个系统调用的时侯,这个系统调用号就被用来指明到底是要执行那个内核函数(服务例程)。

为了把系统调用号与相应的服务例程关联起来,内核利用了一个系统调用表,存放sys_call_table数组中,它是一个函数指针数组,每一个函数指针都指向其系统调用的封装例程,有NR_syscalls个表项,第n个表项包含系统调用号为n的服务例程的地址。

在实际执行0x80号中断向量所对应的中断处理程序(system_call)之前,CPU首先要进行堆栈切换,即从用户态切换到内核态。从中断处理函数中返回时,程序当前栈还要从内核栈切换回用户栈。


对于参数传递,Linux也是通过寄存器完成的。Linux最多允许向系统调用传递6个参数,
分别依次由%ebx,%ecx,%edx,%esi,%edi和%ebp这个6个寄存器完成

在Linux中,EAX寄存器是负责传递系统调用号的。

系统调用是比较费时间的,主要是因为用户态和内核态的切换要做的事情比较多

  • 33
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值