内核如何将进程限制在自己的内存池中?

How does kernel restrict processes to their own memory pool?

这纯粹是学术问题,与任何OS

无关

我们有 x86 CPU 和操作内存,这个内存类似于一些内存池,它由可以读取或写入的可寻址内存单元组成,使用 MOV 指令的地址 CPU(我们可以将内存从/移到这个内存池)。

鉴于我们的程序是内核,我们可以完全访问整个内存池。然而,如果我们的程序不直接在硬件上 运行,内核会创建一些 "virtual" 内存池,它位于物理内存池内的某个地方,我们的进程将其视为物理内存池并可以写入它,从中读取,或通常通过调用 sbrkbrk(在 Linux 上)之类的东西来更改其大小。

我的问题是,这个虚拟池是如何实现的?我知道我可以阅读整个 linux 源代码,也许一年后我就能找到它,但我也可以在这里问 :)

我假设正在使用以下 3 种可能的解决方案之一:

我之所以问,是想了解 运行 程序在内核背后是否有任何开销(我们不考虑内核本身实现的多线程造成的开销)或 while 运行 在 CPU 上本地编程(没有 OS),以及可能使用类似技术的计算机虚拟化导致的内存访问开销。

在普通系统上,内存保护是在 MMU 或内存管理单元强制执行的,它是一个可配置地将虚拟地址映射到物理地址的硬件块。只允许内核直接配置它,非法操作或转到未映射页面的操作会向内核引发异常,然后内核可以约束违规进程或适当地从磁盘中获取丢失的页面。

虚拟机通常使用 CPU 硬件功能来捕获和模拟特权操作或那些与硬件状态直接交互的操作,同时允许普通操作直接 运行,因此总体上适中速度惩罚。如果这些都不可用,则必须模拟整个事情,这确实很慢。

当您提到硬件功能时,您是在正确的轨道上。这是一个称为 protected mode 的特性,由 Intel 在 80286 型号上引入 x86。它随着时间的推移而发展和变化,目前 x86 有 4 种模式。

处理器在 实模式 中启动 运行 之后,特权软件(ring0,例如您的内核)可以在这些模式之间切换。

虚拟寻址是使用处理器支持的 paging mechanism (How does x86 paging work?) 实现和强制执行的。