要回答您的问题,您需要更多地了解内核及其用于管理资源(CPU、内存等)并为应用程序提供优雅抽象的技术。
首先我想明确一点,“虚拟内存”是现代操作系统采用的一种内存管理技术;它提供了各种好处,例如进程隔离,通过保护,允许多个程序一起运行,允许大小大于系统中存在的物理内存的程序。在这种技术下,还有两个术语“虚拟内存”和“虚拟地址空间”;它们不一样,但仍然密切相关。(您会想知道虚拟内存如何既是一种技术又是一种概念,但是是的,这是正确的,您将在下面理解)
在计算机科学中,“记忆”一词有两种含义。第一个是用于存储数据的东西(寄存器、缓存、RAM、ROM、HDD 等)。第二个,与主内存(即RAM)同义。当您逐字替换时,“虚拟内存”只不过是“虚拟内存”'。这是系统中所有时间可用的空间总量,程序在其中加载以供执行。所以这不过是物理 RAM 内存 + 内核分配的辅助存储上的交换内存。因此,如果您在安装时由内核预留 2GB 的 RAM 和 4GB 的交换空间,那么您系统的虚拟内存为 6GB。我不会在这里解释更多关于交换内存的内容,因为这会偏离主题。
转到虚拟地址空间。因此,要理解这一点,您需要稍微调整一下自己的思想。正如名称本身“虚拟”所说,地址空间在现实中并不存在!这只是内核给应用程序程序员创造的一种错觉(为了实现我在第 2 段中提到的许多好处)所以每个进程都被内核赋予了一个单独的虚拟地址空间。(如果系统中没有内核并且你在硬件上运行你的应用程序,那么它会使用物理地址空间,即 RAM 作为它的地址空间)所以在一台具有 32 位地址寄存器的机器上,内核可以为每个进程提供 2^32 = 4GB 的虚拟地址空间。(所以这个虚拟地址空间范围随着硬件架构的变化而变化。
重要的是,这个虚拟地址空间就在空中!!你现在会想,如果只是在空中,那进程的代码、数据怎么可能被执行。是的,这需要映射到物理内存。它如何映射到物理内存是由内核使用称为分页的概念来管理的。所以现在你可以看到内核是如何使用虚拟地址空间实现进程隔离的。所以每个进程可以生成的地址在 0 到 4GB 之间(为了简单起见,假设系统有 32 位地址寄存器),所以这是在它的整体范围内。它对系统中运行的任何其他进程一无所知。所以就像每个进程都被包装在一个单独的空间中。
所以内核代码也像另一个进程/实体。因此,如果内核要驻留在完全不同的地址空间中。那么应用程序就没有办法与内核交互了。如果应用程序不能与内核通信并且内核不能与应用程序通信,那么内核对驱动系统没有用处。所以现在的问题是——如何让应用程序进程与内核交互?
一个选项是 - 如果内核代码存在于应用程序进程的虚拟地址空间中,那么它们可以相互交互。这就是内核代码存在于每个进程的虚拟地址空间中的原因,因为每个进程都需要与内核通信。不要担心内核代码不会为每个进程物理复制。正如我之前提到的,VAS 只是一种错觉,因此物理内存中只会存在一个内核代码副本,并且所有虚拟地址空间都将引用它(通过分页)。在 linux 的情况下,内核将被放置在 C000 0000 到 FFFF FFFF 之间的高位地址空间(即在 VAS 中为内核保留 1GB 的原因),其余 3GB(从 0000 0000 到 BFFF FFFF)允许应用程序利用。内核所在的虚拟地址空间称为内核空间,应用程序所在的虚拟地址空间称为用户空间。如果你仔细观察,你会想出一个问题,如果应用程序代码和内核代码都驻留在同一个虚拟地址空间中,并且由于内核驻留在预先定义好的地址位置,那么这不可能吗?让应用程序代码破坏内核代码!哎呀,起初它看起来是可能的,但它不能。原因是 - 这在硬件的帮助下受到保护。处理器上会有一个标志,指示执行模式是 SUPERVISOR MODE 还是 USER MODE。内核空间代码应在 SUPERVISOR MODE 下执行(适当设置该标志),而用户空间代码应在 USER MODE 下执行。因此,如果您处于用户模式并尝试访问/修改内核空间中的代码,则会引发异常!(处理器根据指令尝试访问的地址来了解它。如果它高于 C000 0000 那么它可以很容易地检测到它正在尝试访问内核空间代码并且当前执行模式没有适当的权限,因为该标志是使用 USER MODE 权限设置的)。请注意:在 SUPERVISOR 模式下,处理器提供对附加指令集的访问。因为该标志是使用 USER MODE 权限设置的)。请注意:在 SUPERVISOR 模式下,处理器提供对附加指令集的访问。因为该标志是使用 USER MODE 权限设置的)。请注意:在 SUPERVISOR 模式下,处理器提供对附加指令集的访问。
我希望如果您了解这个概念,您可以回答自己的问题。在解释概念本身的同时,我已经直接回答了您的许多问题。