根据我的理解,当中断被触发时(例如:系统调用、按下键盘按键等),CPU会在内核模式下执行内核代码,但我想知道我们是否可以有一个独立运行的程序(无需在内核模式下触发的中断。
我的意思是:当调度程序将执行切换到用户模式下的进程时,它就会被执行,但是我们是否可以有一个调度程序将执行切换到的“进程”,但这个“进程”在内核模式下运行(不确定我们是否可以将在内核模式下运行的程序称为“进程”)?
答案1
为了回答这个问题,我首先需要澄清一些术语。
虚拟内存地址分为用户空间和内核空间。在某些体系结构上,两者都是单个线性地址空间的一部分,在其他体系结构上,两者是独立的地址空间。
CPU 在任何给定时间都运行在用户模式或者内核模式。在内核模式它将拥有更多特权,例如可以读取和写入用户空间和内核空间。有些CPU有更多的特权级别。例如,AMD64 兼容 CPU 有四个特权级别,操作系统可以使用这些特权级别,尽管 Linux 仅使用两个特权级别。
当CPU运行在用户模式时,它可以操作指向内核空间的指针,但如果它尝试访问这些指针指向的内容,则会引发异常。在用户模式下运行时,CPU 只能读取、写入和执行用户空间中的字节,并且可能会受到其他限制(例如,内存映射可以配置为不允许在同一范围内写入和执行)。
从用户模式,您只能通过异常或中断进入内核模式,这会导致从内核先前配置的内核空间中的地址开始执行。因此,没有直接的方法可以让用户空间中的代码在内核模式下执行。
然而,内核代码有可能跳转到用户空间中的地址,但这不是一个好主意。如果您以加载内核模块的权限运行(这通常意味着以 root 身份运行),那么您可以在用户空间内存中构造一个模块,然后将其加载到内核中并让它跳回用户空间中的代码。但无论你想做什么,都有比这更好的方法来实现它。
在Linux中有一个称为内核线程的概念。内核线程与用户线程的不同之处在于它们没有用户空间。这些线程始终处于内核模式。出于性能原因,上下文切换在切换到内核线程时可能会保留当前用户空间,因此如果内核线程尝试访问用户空间(这将是一个错误),它将访问最近运行的用户线程的用户空间。
在 Linux 中,进程是一组一个或多个线程,它们共享某些资源,例如在它们之间使用相同的用户空间。 Linux 非常灵活,允许线程选择共享哪些资源和不共享哪些资源。