我知道存在系统调用是为了提供对用户空间中不允许的功能的访问,例如使用 read()
访问硬盘驱动器。系统调用。我也明白这些是由用户模式层以库调用的形式抽象出来的,比如 fread()
, 以提供跨硬件的兼容性。
所以从应用程序开发人员的角度来看,我们有类似的东西;
//library //syscall //k_driver //device_driver
fread() -> read() -> k_read() -> d_read()
我的问题是;是什么阻止我内联
fread()
中的所有指令和 read()
函数直接进入我的程序?指令是相同的,所以 CPU 应该以相同的方式运行?我还没有尝试过,但我认为由于某种原因我失踪了,这不起作用。否则任何应用程序都可能获得任意内核模式操作。TL;DR:什么允许系统调用“进入”应用程序不可复制的内核模式?
最佳答案
系统调用本身不会进入内核。更准确地说,例如,就您的应用程序而言,您调用的 read 函数仍然是一个库调用。什么 read(2)
内部是否正在使用一些中断或 syscall(2)
调用实际的系统调用汇编指令,取决于 CPU 架构和操作系统。
这是用户态代码执行特权代码的唯一方式,但它是一种间接方式。用户态和内核代码在不同的上下文中执行。
这意味着您不能将内核源代码添加到您的用户态代码中,并期望它做任何有用的事情,但会崩溃。特别是,内核代码可以访问与硬件交互所需的物理内存地址。用户空间代码仅限于访问没有此功能的虚拟内存空间。此外,允许用户态代码执行的指令是 CPU 支持的指令的子集。一些 I/O、中断和虚拟化相关指令是禁止代码的例子。它们被称为特权指令,需要根据 CPU 架构处于较低的环或 super 模式。
关于security - Linux 系统调用和内核模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16738636/