为什么“读取”必须是在“内核模式”下运行的系统调用?

据我所知,UNIX函数read()会引起中断(TRAP)并调用系统调用read 。 我还记得在调用系统调用read之前必须切换到“内核模式”,并且切换是昂贵的。

我想知道为什么read操作必须委托给“内核模式”的系统调用,而不是完全在“用户模式”中完成。

例如,如果在“用户模式”中可能存在一个pipe理文件访问权限的服务,则read操作只需请求该服务,而不会干扰内核。

而对于磁盘驱动程序来说,这个链接就是这么说的

设备驱动程序可以在用户模式或内核模式下运行

有没有人有这个想法? 为什么read必须在内核模式?

首先:调用内核的代价非常昂贵。 它曾经是当造成异常/陷阱/故障/中断是在x86系统中从用户模式切换到内核模式的唯一方式,但是所有这一切都随着systenter / sysexit机器代码指令的改变而变化,轻量级转换。

就耗时而言,即使是昂贵的,处理字符和块设备驱动程序的系统调用也应该以内核模式运行,因为处理硬件设备涉及硬件寄存器的读写,硬件寄存器可以通过内存映射或直接访问I / O端口。

这些寄存器必须受到保护,以免受用户空间进程的访问。 不这样做可能会导致任何进程不使用已建立的API来读取文件,并直接使用硬件寄存器来读取和写入设备。 在带有文件的磁盘的情况下,这将允许用户进程完全绕过文件系统,从而允许所有的安全和许可系统。

因此,如果我们需要保护这些硬件寄存器,以便用户进程不能使用它们,那么使用它们的代码就不能像其他任何用户进程一样在特权级别运行。 因此,他们运行在另一个(更多的特权)模式,这就是所谓的“内核模式”。

考虑一下如果你配置一个Linux系统, /dev/sda (通常是根文件系统所在的主要硬盘)被读/写给任何人和每个人:

 # chmod 666 /dev/sda 

这样做或多或少相当于将硬盘设备暴露给任何用户进程。 您可以有效地编写一个程序,可以打开,读取和写入存储在此设备中的文件,但是同时您可以编写一个程序来打开,读取和写入分区内的任何文件,而不管这些文件有哪些权限。

也就是说,有些情况下系统只运行可信的应用程序。 这种类型的系统不需要通用系统中存在的保护级别,因此可以通过不依赖于API层来提高速度以将进程与硬件隔离而受益。 最广为人知的例子将是一个videoconsole系统。 我记得Windows CE用来运行所有的程序和设备驱动程序也是同样的特权。

是不是操作系统的设计方式。 操作系统的定义是处理计算机的硬件并为用户提供资源。 操作系统也有用户模式和内核模式的概念(如你所说)。

通过具有这些概念,操作系统定义了一个特定的行, 用户可以做什么,什么不行。 让他们管理硬件绝对是操作系统不希望用户做的事情。

read通常涉及硬件访问。 访问硬件非常麻烦并且容易出错,并且可能使计算机处于不可用状态。 操作系统使用驱动程序来控制计算机的硬件。

发出一个read (假设一个硬盘IO)通常会使一个驱动程序向磁盘控制器发送一组命令,读取它的输出,并将其传送到主存储器等。这是危险的操作,不应该被信任到用户模式。

如果在用户模式下会有服务来处理这个问题。 上下文切换仍然需要完成,因为服务将作为另一个进程运行。

当然可以做到这一点的操作系统。 但是现代操作系统并不是为了实现这种行为而设计的。

还有其他方法来构建依赖于微内核的操作系统。 一个微内核只是尽最大努力让电脑开始工作,而将其他所有模块都留给其他模块。 这意味着,如果一个模块崩溃,系统仍然起来。 这是特定的驱动程序,文件系统等的情况。我不知道微内核是否让这些运行在用户空间。

希望这可以帮助!