访问内存时如何通知操作系统内核?

Posted

技术标签:

【中文标题】访问内存时如何通知操作系统内核?【英文标题】:How does OS kernel get notified when memory is accessed? 【发布时间】:2021-06-04 16:06:53 【问题描述】:

据我所知,OS内核维护着从虚拟地址到物理地址的转换,用户空间程序使用虚拟地址,CPU使用物理地址。

既然所有的机器代码都是由 CPU 执行的,那么 OS 内核如何知道一条内存访问指令被取走,并将虚拟地址转换为物理地址呢? CPU 可以执行syscall 将控制权转移给内核,但内存读/写不是通过syscall 完成的。我很困惑。

例如,考虑下面的代码(地址3只是为了简化,不用担心读/写/执行权限):

int a = *(int *)3;

这是编译成

movl    $3, %ecx
movl    (%rcx), %edx
movl    %edx, -8(%rbp)

OS内核加载程序后,将IP寄存器设置为入口点,并做一些其他准备,然后让CPU执行指令。当 CPU 执行movl (%rcx), %edx 时,OS 内核如何知道是它应该干预的时间,阻止 CPU 访问物理地址0x3

【问题讨论】:

【参考方案1】:

CPU 中有一个组件称为内存管理单元。它负责在执行内存访问指令时将虚拟地址转换为物理地址。

如果虚拟地址当前没有映射到 RAM,它会触发中断。这会暂停进程并告诉操作系统它需要将适当的内存带入 RAM。它试图访问的地址存储在一个寄存器中,因此操作系统知道要分页。

【讨论】:

【参考方案2】:

您的假设是错误的,因为 CPU 确实转换了虚拟地址。

分页和虚拟寻址由 CPU 实现,操作系统使用这种实现。操作系统不保留虚拟地址数据库,它保留页表数据库,以便在需要时可以修改它们,例如在上下文切换期间。此外,操作系统需要跟踪哪个页面用于什么。

MMU 是负责将虚拟地址转换为物理地址的 CPU 单元,它通过在缓存中查找页表来实现这一点。 CPU 或 MMU 也有一个称为 TLB 的缓存,它保存虚拟地址转换以使转换更快。否则,CPU 将需要执行多次 RAM 读取来收集所需的信息,以便为每次内存访问进行转换。由于 RAM 与 CPU 相比速度较慢,这会使计算机速度变慢。

【讨论】:

以上是关于访问内存时如何通知操作系统内核?的主要内容,如果未能解决你的问题,请参考以下文章

Linux进程内存如何管理?

linux /proc目录说明(访问内核数据结构,修改内核设置)

Linux的内核空间和用户空间是如何划分的(以32位系统为例)?

linux进程为啥有用户栈和内核栈,

通知 OpenCL 内核许多内存对象的正确方法?

内存管理:用户模式和内核模式