除了使用系统调用之外,我们什么时候会跳转到进程虚拟内存的内核部分? (在Linux中)

除了使用系统调用之外,我们什么时候会跳转到进程虚拟内存的内核部分? (在Linux中)

这是我之前的后续问题问题

根据答案,系统调用是我们跳转到进程虚拟内存的内核部分的一个示例。

  1. 除了系统调用之外,正常进程(非内核)使用这部分虚拟内存的其他示例还有哪些?就像有没有任何函数调用可以直接跳转到这个内核部分或者..?

  2. 当我们跳转到这部分内存时,处理器是否会自动将内核模式位设置为1以便我们的进程访问这部分内存,或者不需要设置该位?

  3. 该内核部分内部的所有执行是否都不需要上下文切换到内核进程?

(我不想在评论中提出这些后续问题,所以我打开了另一个线程。)

在此输入图像描述

答案1

  1. 在用户模式下运行的进程根本无法访问内核的地址空间。处理器可以通过多种方式切换到内核模式并运行内核代码,但它们都是由内核设置并在明确定义的上下文中发生:运行系统调用、响应中断或处理故障。系统调用不涉及直接调用内核代码;它们涉及一种特定于体系结构的机制,要求 CPU 将控制权转移到内核,以代表调用进程运行由其编号标识的特定系统调用。 LWN 有一系列文章解释其工作原理:系统调用剖析 第一部分,第二部分, 和附加内容

    如果进程尝试访问内核地址空间中的内存,它将切换到内核模式,但会由于故障而切换;然后,内核将因分段违规而终止该进程 ( SIGSEGV)。

    在 32 位 x86 上,有使用远调用切换到内核模式的机制,呼叫门;但 Linux 不使用它。 (它们依赖于特殊的代码段描述符,而不是调用内核地址。)

  2. 参见上文:您无法跳转到内核内存。在上述情况下,当转换到内核模式时,CPU 检查是否允许转换,如果允许,则使用适合所使用的体系结构的任何机制切换到内核模式。在 x86 Linux 上,这意味着从环 3 切换到环 0。

  3. 转换到内核模式不涉及进程的更改,所以是的,所有这一切都在没有上下文切换的情况下发生(由内核计算)。

答案2

1 & 2. 不,用户程序不能简单地使用跳转指令进入内核内存。不允许这样做。 CPU不会自动设置“内核位”以允许这样的跳转成功...(也许某些CPU具有这样的功能,但是安全的Linux端口会禁用此功能)

...实际上,由于您正在以没有权限的方式访问页面,因此您将进入内核:-)。它以受控方式进入,其工作原理与系统调用非常相似,但我们称之为“页面错误”。 CPU 将提供访问内核的详细信息。对于您描述的访问类型,内核会将其视为程序中的错误:-)。它将向您的程序发送致命信号(SIGSEGV)。

答案3

从技术上讲,内核内存可以映射到进程,不可读、只读或读写,甚至可能通过跳转到该内存中存储的代码来由进程执行。这是一种提高某些系统调用速度的技术,可以安全地运行代码来在进程中而不是在内核中处理系统调用。它还可以包括数据,例如包含内核提供的时钟值的内存地址,因此进程不必中断,因此系统可以进入内核。

进程也可以通过INT 0x80通过中断进入内核的系统调用,这是许多汇编程序员所熟悉的,但这当然不是内核可以提供的唯一机制。没有硬性规定内核和用户地址空间必须完全分开。

不管Linux采用什么方式,将内核代码和数据放入进程中在技术上肯定是可行的。出于与上下文切换和 TLB 相关的性能原因,Linux 也会例行地将内核内存放入进程中,但由于内核的许多区域都是敏感的,因此进程通常无法读取它们。

相关内容