据我所知,操作系统内核维护着从虚拟地址到物理地址的转换,用户空间程序使用虚拟地址,CPU使用物理地址。
既然所有的机器码都是由CPU执行的,那么OS内核如何知道内存访问指令被执行,并将虚拟地址转换为物理地址呢?CPU可以执行syscall
来将控制传递给内核,但是内存读/写不是通过syscall
来完成的。我很困惑。
int a = *(int *)3;
编译成
movl $3, %ecx
movl (%rcx), %edx
movl %edx, -8(%rbp)
程序被操作系统内核加载后,将IP寄存器设置为入口点,并做一些其他准备,然后让CPU执行指令。当CPU执行movl (%rcx), %edx
时,操作系统内核如何知道是该介入的时候,阻止CPU访问物理地址0x3
?
CPU有一个组件叫做内存管理单元。它负责在执行内存访问指令时将虚拟地址转换为物理地址。
如果虚拟地址当前没有映射到RAM中,它将触发中断。这将挂起进程并告诉操作系统它需要将适当的内存放入RAM中。它试图访问的地址存储在寄存器中,因此操作系统知道要分页的内容。
你的假设是错误的,因为CPU做转换虚拟地址
分页和虚拟寻址由CPU实现,操作系统使用该实现。操作系统不保留虚拟地址的数据库,它保留页表的数据库,以便在需要时修改它们,例如在上下文切换期间。此外,操作系统需要跟踪哪个页面用于什么。
MMU是负责虚拟地址到物理地址转换的CPU单元,它通过在缓存中查找页表来完成转换。此外,CPU或MMU有一个称为TLB的缓存,它保存虚拟地址转换以使转换更快。否则,CPU将需要执行多次RAM读取来收集所需的信息,以便为每次内存访问进行转换。由于RAM比CPU慢,这将使计算机更慢。