Linux内核之系统调用

系统调用

为了和用户空间的进程进行交互,内核提供了一组界面,应用程序可以通过此访问硬件设备和其他操作系统资源。

系统调用在用户空间进程和硬件设备之间添加了一个中间层,作用如下

  • 为用户空间提供了硬件的抽象界面,当需要读文件时,应用程序可以不用管磁盘类型和介质,甚至不用去管文件所在的文件系统是哪种类型
  • 系统调用保证了系统的稳定和安全,内核作为硬件设备和应用程序之间的中间人,可以基于权限和其他规则对需要进行的访问进行裁决
  • 如果应用程序可以随意访问硬件而内核又对此一无所知的话,几乎无法实现多任务和虚拟内存(即内核需要有管理能力)。在Linux中,系统调用是用户空间访问内核的唯一手段(process不能随便访问内核了,内核也只需处理system_call()即可)

image-20220306144433169

API、POSIX、和C库

一般情况下,应用程序通过API而不是直接通过系统调用来编程。而API不一定和内核提供的系统调用对应。

一个API定义了一组应用程序使用的编程接口。(可理解为实现某种功能的函数)它们可以实现成一个系统调用,也可以通过调用多个系统调用来实现,而完全不使用任何系统调用也不存在问题。

image-20220306145921933

实际上,API可以在各种不同的操作系统上实现,给应用程序提供完全相同的接口,而它们本身在这些系统上的实现却可能迥异。

Linux的系统调用作为C库的一部分

image-20220306145543125

  • C库实现了Unix系统的主要API,包括标准C库函数和系统调用
  • 程序员只需关心API,而内核只关心system_call

系统调用

系统调用通常通过函数进行调用,通常都需要定义一个或几个参数。一般返回0表示成功,返回负值表示失败,Unix系统调用在出现错误的时候会把错误码写入errno全局变量,通过调用perror()库函数,可以把该变量翻译成用户可以理解的错误字符串。

//getpid系统调用
asmlinkage long sys_getpid(void)
{
    return current->tgid;
}
  • asmlinkage限定词,通知编译器仅从栈中提取该函数的参数,所有系统调用都需此限定词
  • 系统调用git_pid()在内核中被定义成sys_getpid(),这是Linux中所有系统调用都要遵守的命名规则

系统调用号

Linux中,所有系统调用被赋予一个系统调用号,当用户空间进程执行一个系统调用,这个系统调用号就被用来指明到底执行哪个系统调用,进程不会提及系统调用的名称

  • 系统调用号一经分配不能再有变更,否则编译好的程序会崩溃
  • 如果系统调用被删除,那么它的系统调用号也不能被回收
  • Linux有一个专门处理访问无效的系统调用情况的系统调用,sys_ni_syscall(),如果某个系统调用被删除,这个函数就填补空位

系统调用处理程序

用户空间的程序无法执行内核代码,它们不可直接调用内核空间函数,因为内核空间地址受到保护。

应用程序应以某种方式通知系统自己需要执行一个系统调用,希望系统切换到内核态。

通知内核的机制是靠软中断实现的:

  • 通过引发一个异常来促使系统切换到内核态去执行异常处理程序——系统调用处理程序

  • x86系统的软中断由int $0x80指令产生,这条指令触发一个异常导致系统切换到内核态并执行第128号异常处理程序,该程序正是系统调用处理程序,该处理程序叫做system_call(),与硬件体系结构关联紧密,由汇编语言编写

  • 所以系统调用陷入内核方式都一样,我们还需把系统调用号传给内核才知道要调用哪个。这个传递动作通过在触发软中断前把调用号装入eax寄存器实现

  • 除了系统调用号以外,大部分系统调用还需要一些参数输入,所以发生异常的时候,应该把这些参数由用户空间传给内核。也可以把这些参数也存放在寄存器中,给用户空间的返回值也存放在寄存器中。

    image-20220306152441916

read()函数是API,调用后通过软中断通知内核需要执行一个系统调用,切换到内核态后才可以调用系统调用sys_read()

系统调用上下文

内核执行系统调用时处于进程上下文(进程保存信息到PCB中),current指针指向当前触发系统调用那个进程

在进程上下文中,内核可以休眠并且可以被抢占

  • 能够休眠说明系统调用可以使用内核提供的绝大部分功能
  • 被抢占说明当前进程可被其他进程抢占,比如另一个进程也启动了相同的系统调用,所以系统调用需要可重入
  • 当系统调用返回时,控制权仍在system_call(),它最终会负责切换到用户空间

参考

  • [(83 封私信 / 83 条消息) Linux 系统调用 - 搜索结果 - 知乎 (zhihu.com)](https://www.zhihu.com/search?type=content&q=Linux 系统调用)
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值