ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux系统调用

2020-02-21 10:38:10  阅读:180  来源: 互联网

标签:调用 函数 中断 系统 Linux 执行 CPU


系统调用是操作系统内核提供给应用程序的基础接口,需要运行在操作系统的核心模式下,以确保有权限执行某些 CPU 特权指令。

Linux 系统提供了功能非常丰富的系统调用,涵盖了文件操作、进程控制、内存管理、网络管理、套接字操作、用户管理、进程间通信等各个方面。

执行如下命令,可列出系统中所有的系统调用名称。

man syscalls

系统调用的两种调用方式

1.系统调用由指派的编号来标识,通过 syscall 函数以编号为参数可直接被调用,完整的系统调用编号都定义在 sys/syscall.h 文件。
syscall 函数原型为:

int syscall(int number, ...);

2.利用 glibc 提供的包装函数将这些系统调用包装成名字自解释的函数。这个过程,包装函数并没有做太多额外工作,主要是检查参数,将它们拷贝到合适的寄存器中,接着调用指定标号的系统调用,之后再根据结果设置 errno,供应用程序检查执行结果,以及其他相关工作。

两种调用方式,在功能上可以认为是完全等价的,但在易读、易用性上,glibc 包装函数则更有优势。当然,如果包装函数无法满足某些特殊应用场景需求,还可以使用 syscall 函数直接执行系统调用。

系统调用的两种执行过程

1.基于中断方式
系统调用的实现代码是内核代码的一部分。执行系统调用代码,首先需要将系统从用户模式切换到核心模式。

早期的系统调用通过软中断实现模式的切换,而中断号属于系统稀缺资源,不可能为每个系统调用都分配一个中断号。

在 Linux 的实现中,所有的系统调用共用 128 号中断,其对应的中断处理程序是 system_call,所有的系统调用都会转到这个中断处理程序中。

接着,system_call 会根据 EAX 传入的系统调用标号跳转并执行相应的系统调用程序。如果需要更多的参数,会依次用 EBX、ECX、EDX、EDI 进行传递。函数执行完成之后,会把结果放到 EAX 中返回给应用程序。

由此可知,一次系统调用便会触发一次完整的中断处理过程。在每次中断处理过程中,CPU 都会从系统启动时初始化好的中断描述表中,取出该中断对应的门描述符,并判断门描述符的种类。

在确认门描述符的级别(DPL)不比中断指令调用者的级别(CPL)低之后,再根据描述符的内容,将中断处理程序中可能用到的寄存器进行压栈保存。最后执行权限提升,设置 CS 和 EIP 寄存器,以使 CPU 跳转到指定的系统调用的代码地址,并执行目标系统调用。

2.基于 SYSENTER 指令
再仔细审视基于中断方式的系统调用的执行过程,不难发现,前面很多处理过程都是固定的,其实很没必要,如门描述符级别检查、查找中断处理程序入口,等等。

为了省去这些多余的检查,Intel 在 Pentium II CPU 中加入了新的 SYSENTER 指令,专门用来执行系统调用。

该指令会跳过前面检查步骤,直接将 CPU 切换到特权模式,继而执行系统调用,同时还增加了几个专用寄存器辅助完成参数传递和上下文保存工作。另外,还相应地增加了 SYSEXIT 指令,用来返回执行结果,并切回用户模式。

在 Linux 实现了 SYSENTER 方式的系统调用之后,就有人用 Pentium III 的机器对比测试了两种系统调用的效率。测试结果显示,与中断方式相比,SYSENTER 在用户模式下因省掉了级别检查类的操作,花费的时间大幅减少了 45% 左右;在核心模式下,因少了一个寄存器压栈保存动作,所花费的时间也减少了 2% 左右。

目前,基于中断方式的系统调用仍然保留着,Linux 启动时会自动检测 CPU 是否支持 SYSENTER 指令,从而根据情况选择相应的系统调用方式。

系统调用的标准使用方法

系统调用的标准使用方法可总结为:根据包装函数返回值的正负,确定系统调用是否成功。如果不成功,进一步通过 errno 确定出错原因,根据不同的出错原因,执行不同的操作;如果成功,则继续执行后续的逻辑。代码示例如下:

int ret = syscallx(...);
if(ret < 0)
{
    //有错误了,通过 errno 确定出错的原因,执行不同的操作
}
else
{
    //调用成功,继续干活
}

大多数系统调用都遵循这一过程,errno 是一个整数,可以用 perror 或 strerror 获得对应的文字描述信息。

月棠 发布了53 篇原创文章 · 获赞 22 · 访问量 6万+ 私信 关注

标签:调用,函数,中断,系统,Linux,执行,CPU
来源: https://blog.csdn.net/wushuangge/article/details/104423256

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有