为什么存在系统调用

时间:2018-05-31 14:15:46

标签: c linux-kernel system system-calls glibc

我一直在阅读系统调用及其在Linux中的工作方式。我仍然有更多的阅读要做,但有一件事我没看过,我们为什么需要系统调用呢?

我知道系统调用是来自用户空间程序的请求,内核要做一些事情,但我的问题基本上是:为什么用户空间程序不能自己做这件事?为什么Glibc不执行实际操作而不仅仅是系统调用的包装器?

例如,如果我在程序中调用fopen(),为什么glibc会调用open系统调用?为什么glibc本身不进行操作?

据我所知,这意味着glibc开发人员会有更多的工作,而且他们必须对Linux有深入的了解,但是glibc与Linux内核的关系不是很密切吗?

另外,我知道系统调用函数在CPU的0环上运行......但是真正重点是什么?如果我执行一个程序,我给它明确的运行权限,那么通过分离哪些代码可以在不同的上下文中运行来添加什么安全性,因为你还是给了它所有权限?

7 个答案:

答案 0 :(得分:12)

  

为什么glibc本身不进行操作?

更好的是,在旧的MS / DOS系统中,事情进展得更少:内核代码和用户代码之间没有分离,用户代码可以愉快地直接访问硬件。

这只有两个主要问题:

  • 在单个用户而非多任务系统上工作(相当)很好,但只要多个程序可以在系统中同时运行,就必须同步硬件访问和内存使用=>这些是专用于内核的部分
  • 系统没有保护编码不良的程序。在现代操作系统中,错误的程序可能会崩溃,但系统本身应该存在。在MS / DOS中,程序崩溃通常在系统重启时结束。

由于这些原因,所有现代操作系统(除了一些轻量级嵌入式操作系统)都使用不同用户进程和内核之间的隔离。这只是意味着您需要一种方法来允许用户模式进程从内核中要求特权操作(读取或写入物理磁盘 ):这正是系统调用的目的。

答案 1 :(得分:2)

  

为什么glibc本身不进行操作?

简短回答:因为它不能。

答案很长: 在Linux中运行的程序可以以两种模式运行:UserLand或KernelLand。

Kernel Land拥有所有权利,可以做任何事情,包括与硬件交谈或提供用户空间回调。例如,当您调用fopen()时,内核会对您的文件系统(例如ext4)执行所有脏话,缓存,一切都与SATA控制器通信以访问硬盘上的数据驱动。

GLibc可以使用/dev中内核公开的设备来做到这一点,但这意味着从头开始重新编码所有文件系统层,套接字,防火墙......

内核只为程序员提供了易于使用的API,可以提升权限并与设备通信。 那是Linux(以及最现代的操作系统)的制作方式。

  

通过分隔哪些代码可以在不同的上下文中运行来添加什么安全性,因为您无论如何都要授予它所有权限?

权限由内核管理。如果您没有系统调用,则表示您没有权限。或者您运行的程序是否应该检查自己的权限?再次,它每次都会重新发明轮子。

答案 2 :(得分:1)

如果C实现生成的代码是唯一将在目标系统上运行的代码(因为它适用于许多独立实现,以及非常少量的托管实现),并且如果实现知道< em>正好它将运行什么硬件(对于一些独立的实现来说是真的,但对托管的实现很少),它的运行时库可能能够执行像&#34; fopen&#34;通过直接与存储硬件通信。然而,很少应用这两种情况,更不用说两者都适用。

如果多个程序将使用存储设备,通常需要它们以某种方式协调它们的动作,或者由不同程序执行的操作序列不重叠,并且每个程序都会忘记&#34;任何它认为在任何时候另一个程序可能写入存储状态时都知道存储状态。

否则,假设磁盘包含单个文件,程序#1使用&#34; fopen&#34;打开它阅读。每个目录扇区包含8个条目,因此程序将读取第一个目录扇区并观察到#0#插槽标识感兴趣的文件,而#1-#7是空白的。

现在假设程序#2使用&#34; fopen&#34;创建一个文件来写。它将读取目录扇区,观察插槽#1-#7是空白的,并使用有关插槽#1中新文件的信息重写目录扇区。

最后,假设程序#1想要写一个文件。如果它不知道程序#2,它可能有理由相信它知道目录包含的内容(它之前已经读过它,并且没有理由相信它已被更改),放置有关新文件的信息在插槽#1中,用新版本替换磁盘上的目录扇区,删除程序#2写入的条目。

让两个程序通过操作系统路由其操作可确保当程序#2想要创建其文件时,它可以利用它刚刚读取程序#1的目录这一​​事实(因此不需要重读它)。更重要的是,当程序#1写入文件时,操作系统将知道该目录包含程序#2写入的文件,因此将确保新文件放在插槽#2中。

与其他答案所说的相反,即使在像MS-DOS这样的平台上运行的微型计算机C实现也基本上总是依赖于操作系统来进行文件I / O.有些会包含他们自己的控制台I / O例程,因为MS-DOS中的那些程序的速度大约是它们应该的速度的四倍,但是在使用文件I / O时需要协调意味着很少有程序会尝试这样做自己。

答案 3 :(得分:1)

1-您不想处理低级硬件通信。至少大多数人没有。他们每个人都有数百个命令。

2-犯了一个简单的错误,您的CPU / RAM或I / O设备可能永远无用。

3-当您加入网络时,您可以共享资源。系统调用和内核可以防止您的同事损坏您的硬盘。

答案 4 :(得分:0)

另一个考虑因素是操作系统内核需要通过统一的API为无数种不同类型的硬件提供抽象 - 没有它,你总是会在你的程序中进行特定于设备的调用。

答案 5 :(得分:0)

当先前空闲的磁盘旋转两秒钟,或者网络磁盘连接三十秒时,该库将会做什么?

答案 6 :(得分:0)

你的问题的完整答案非常广泛,但让我举一个基于你关于fopen的问题的简单例子。

让我们说,我们有一个拥有数百或数千用户的大型系统。其中一个用户是人力资源部门,其中包含包含员工机密信息的文件。

如果可以在用户模式下随意访问该磁盘,则系统上的任何人都可以打开系统上的任何文件,包括那些包含机密信息的文件。

换句话说,操作系统管理着SHARED资源。这些包括磁盘,CPU和内存。如果可以在用户模式下控制这些,则无法确保公平地共享这些内容。