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



这纯粹是学术问题,与任何操作系统无关

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

假设我们的程序是内核,我们可以完全访问整个内存池。然而,如果我们的程序不是直接在硬件上运行,内核会在物理内存池中的某个位置创建一些"虚拟"内存池,我们的进程会将其视为物理内存池,并可以对其进行写入、读取或更改其大小,通常通过调用sbrkbrk(在Linux上)。

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

我想这三种潜在的解决方案之一正在被使用:

  • 解释程序的指令(非常无效且不太可能):内核只会读取程序的字节码,并单独解释每条指令,例如,如果它看到访问内存的请求,进程就不允许访问它
  • 创建一些需要使用的操作系统级API,以便读取/写入内存,并禁止访问原始内存,这可能同样无效
  • 硬件功能(可能是最好的,但不知道它是如何工作的):内核会说"亲爱的CPU,现在我将从一些没有特权的进程向您发送指令,请将您的指令限制在内存区域0x00ABC023 - 0xDEADBEEF"CPU不会让用户进程对内存做任何错误的事情,除非内核批准的范围

我之所以这么问,是为了了解在内核后面运行程序时是否有任何开销(我们不要考虑内核本身实现的多线程导致的开销),或者在CPU上本地运行程序时(没有操作系统),以及可能使用类似技术的计算机虚拟化导致的内存访问开销。

当您提到一个硬件功能时,您是在正确的轨道上。这是一种被称为保护模式的功能,由Intel在80286型号上引入x86。随着时间的推移,x86有4种模式。

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

虚拟寻址是使用处理器支持的分页机制(x86分页是如何工作的?)来实现和强制执行的。

在正常系统上,内存保护在MMU或内存管理单元强制执行,MMU是一个可配置地将虚拟地址映射到物理地址的硬件块。只有内核才被允许直接配置它,非法操作或去往未映射页面的操作会给内核带来异常,然后内核可以对有问题的进程进行约束,或者根据需要从磁盘中获取丢失的页面。

虚拟机通常使用CPU硬件功能来捕获和模拟特权操作或那些与硬件状态交互过多的操作,同时允许普通操作直接运行,从而降低总体速度。如果这些都不可用,那么整个事情必须效仿,这确实很慢。

最新更新