我知道存在系统调用是为了提供对用户空间中不允许的功能的访问,例如使用 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 模式。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!