内核如何将进程限制在自己的内存池中?
How does kernel restrict processes to their own memory pool?
这纯粹是学术问题,与任何OS
无关
我们有 x86 CPU 和操作内存,这个内存类似于一些内存池,它由可以读取或写入的可寻址内存单元组成,使用 MOV
指令的地址 CPU(我们可以将内存从/移到这个内存池)。
鉴于我们的程序是内核,我们可以完全访问整个内存池。然而,如果我们的程序不直接在硬件上 运行,内核会创建一些 "virtual" 内存池,它位于物理内存池内的某个地方,我们的进程将其视为物理内存池并可以写入它,从中读取,或通常通过调用 sbrk
或 brk
(在 Linux 上)之类的东西来更改其大小。
我的问题是,这个虚拟池是如何实现的?我知道我可以阅读整个 linux 源代码,也许一年后我就能找到它,但我也可以在这里问 :)
我假设正在使用以下 3 种可能的解决方案之一:
- 解释程序指令(非常低效且不太可能):内核只会读取程序的字节码并单独解释每条指令,例如。如果它看到访问内存的请求,则该进程不允许访问它不会允许它。
- 创建一些 OS 级别 API 需要使用它们来读取/写入内存并禁止访问原始内存,这可能同样无效。
- 硬件特性(可能是最好的,但不知道它是如何工作的):内核会说 "dear CPU, now I will send you instructions from some unprivileged process, please restrict your instructions to memory area
0x00ABC023 - 0xDEADBEEF
" CPU 不会让用户进程对内存做任何错误,除了对于内核批准的范围。
我之所以问,是想了解 运行 程序在内核背后是否有任何开销(我们不考虑内核本身实现的多线程造成的开销)或 while 运行 在 CPU 上本地编程(没有 OS),以及可能使用类似技术的计算机虚拟化导致的内存访问开销。
在普通系统上,内存保护是在 MMU 或内存管理单元强制执行的,它是一个可配置地将虚拟地址映射到物理地址的硬件块。只允许内核直接配置它,非法操作或转到未映射页面的操作会向内核引发异常,然后内核可以约束违规进程或适当地从磁盘中获取丢失的页面。
虚拟机通常使用 CPU 硬件功能来捕获和模拟特权操作或那些与硬件状态直接交互的操作,同时允许普通操作直接 运行,因此总体上适中速度惩罚。如果这些都不可用,则必须模拟整个事情,这确实很慢。
当您提到硬件功能时,您是在正确的轨道上。这是一个称为 protected mode 的特性,由 Intel 在 80286 型号上引入 x86。它随着时间的推移而发展和变化,目前 x86 有 4 种模式。
处理器在 实模式 中启动 运行 之后,特权软件(ring0,例如您的内核)可以在这些模式之间切换。
虚拟寻址是使用处理器支持的 paging mechanism (How does x86 paging work?) 实现和强制执行的。
这纯粹是学术问题,与任何OS
无关我们有 x86 CPU 和操作内存,这个内存类似于一些内存池,它由可以读取或写入的可寻址内存单元组成,使用 MOV
指令的地址 CPU(我们可以将内存从/移到这个内存池)。
鉴于我们的程序是内核,我们可以完全访问整个内存池。然而,如果我们的程序不直接在硬件上 运行,内核会创建一些 "virtual" 内存池,它位于物理内存池内的某个地方,我们的进程将其视为物理内存池并可以写入它,从中读取,或通常通过调用 sbrk
或 brk
(在 Linux 上)之类的东西来更改其大小。
我的问题是,这个虚拟池是如何实现的?我知道我可以阅读整个 linux 源代码,也许一年后我就能找到它,但我也可以在这里问 :)
我假设正在使用以下 3 种可能的解决方案之一:
- 解释程序指令(非常低效且不太可能):内核只会读取程序的字节码并单独解释每条指令,例如。如果它看到访问内存的请求,则该进程不允许访问它不会允许它。
- 创建一些 OS 级别 API 需要使用它们来读取/写入内存并禁止访问原始内存,这可能同样无效。
- 硬件特性(可能是最好的,但不知道它是如何工作的):内核会说 "dear CPU, now I will send you instructions from some unprivileged process, please restrict your instructions to memory area
0x00ABC023 - 0xDEADBEEF
" CPU 不会让用户进程对内存做任何错误,除了对于内核批准的范围。
我之所以问,是想了解 运行 程序在内核背后是否有任何开销(我们不考虑内核本身实现的多线程造成的开销)或 while 运行 在 CPU 上本地编程(没有 OS),以及可能使用类似技术的计算机虚拟化导致的内存访问开销。
在普通系统上,内存保护是在 MMU 或内存管理单元强制执行的,它是一个可配置地将虚拟地址映射到物理地址的硬件块。只允许内核直接配置它,非法操作或转到未映射页面的操作会向内核引发异常,然后内核可以约束违规进程或适当地从磁盘中获取丢失的页面。
虚拟机通常使用 CPU 硬件功能来捕获和模拟特权操作或那些与硬件状态直接交互的操作,同时允许普通操作直接 运行,因此总体上适中速度惩罚。如果这些都不可用,则必须模拟整个事情,这确实很慢。
当您提到硬件功能时,您是在正确的轨道上。这是一个称为 protected mode 的特性,由 Intel 在 80286 型号上引入 x86。它随着时间的推移而发展和变化,目前 x86 有 4 种模式。
处理器在 实模式 中启动 运行 之后,特权软件(ring0,例如您的内核)可以在这些模式之间切换。
虚拟寻址是使用处理器支持的 paging mechanism (How does x86 paging work?) 实现和强制执行的。