为什么内核被映射到与进程相同的地址空间?

17
这是一个关于以下问题的阐述:为什么说内核在进程地址空间中? 引用: 这可能是一个愚蠢的问题,但它突然在我的脑海中出现。有关进程地址空间和虚拟内存布局的所有文本都提到进程地址空间已为内核保留了空间。例如,在32位系统上,Linux内核中有1GB的地址空间专门为内核保留(其他操作系统可能不同)。
我只是想知道为什么说内核在进程地址空间中,因为进程不能直接寻址内核。为什么我们不说内核有一个单独的地址空间而不是进程地址空间,为什么我们不能为内核本身设置一个不同于进程页表的不同页表?
我能否得到一个针对Linux(Debian或Ubuntu)特定操作系统的解释?
4个回答

32

回答问题的另一个部分 - 内核部分映射到每个进程的地址空间,部分出于效率/性能原因(我确定还有其他原因)。

在大多数现代硬件上,更改安全级别(从而允许访问否则受保护的页面,如Alexey的答案所述)以执行系统调用和其他内核提供的功能比更改安全级别和整个虚拟内存映射更快,以及与完整上下文切换相关的所有关联TLB缓存刷新和其他所有任务。

由于系统调用可能是相当频繁的事件,因此在Linux和许多其他地方演变出的设计试图最小化利用内核服务的开销,并将内核代码和(至少一些)数据映射到每个进程中。


所以我将其视为,有一个主1GB内核地址空间,在每个进程的虚拟内存区域中都有一个视图/反映。也就是说,如果我有3个用户进程在运行,每个进程都有4GB的虚拟区域。在每个进程的4GB中,有1GB指向相同的内核地址空间? - Diwakar Sharma
是的,这本质上就是内存映射的方式。但是,需要注意的是,由于页面表和TLB条目中设置了保护位,用户进程无法访问那1GB内核区域。 - Evan

14

这里的一个进程“拥有”整个虚拟地址空间,包括内核和用户部分。

它不能查看和更改内核代码和数据,并不是因为不同的地址空间,而是由于页面表中设置了不同的访问权限。内核页面被设置成普通应用程序无法访问。

然而,通常将一个整体的两个部分称为内核空间和用户空间,这可能会令人困惑。


6
另一个重要原因是内核位于进程地址空间中,这意味着内核可以访问当前进程的用户代码/数据,即虚拟地址空间0~3G。对于我的糟糕英语表示抱歉,因为我不是以英语为母语的人。

4
假设在每个进程地址空间中没有映射内核,那么会发生什么呢?例如,当定时器中断发生时,处理器使用IDT(中断描述符表)调用ISR(中断服务例程)。如果没有映射内核,则IDT地址将变得无效,最终会导致三重错误。

自上一次查看文档以来已经过了一些时间,但当时x86 call/interrupt gates可以在段之间传递执行。将IDT的选择器设置为类似GDT的方式即可。内核映射到用户空间的原因主要是与性能相关。内核还可以随时设置自己的不同页面表以访问所需物理内存,但这也会清除所有缓存并严重降低性能。 - user3125367

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接