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

这是一个需要说明的问题: 为什么内核被说成在进程地址空间?

这可能是一个愚蠢的问题,但它只是popup在我的脑海里。 所有关于进程地址空间和虚拟内存布局的文本都提到进程地址空间为内核预留了空间。 例如在32位系统上,进程地址空间是4GB,其中1GB是为Linux内核保留的(在其他操作系统上可能不同)。

我只是想知道为什么当进程无法直接访问内核时,为什么内核被说成是在进程地址空间中。 为什么我们不说内核具有一个独立的地址空间而不是一个进程,为什么我们不能为内核本身提供一个与进程的页表分开的不同的页表?

我可以得到关于Linux(Debian或Ubuntu)特定操作系统的解释。

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

它无法偷看和戳内核代码和数据不是由于不同的地址空间,这是由于在页表中设置不同的访问权限/权限。 内核页面的设置方式使常规应用程序无法访问它们。

但是,习惯上把一个整体的两个部分称为内核空间和用户空间,这可能会造成混淆。

为了回答这个问题的另一部分 – 内核被映射到每个进程的地址空间部分出于效率/性能的原因(也有其他人,我敢肯定)。 在大多数现代硬件上,为了执行系统调用和其他内核提供的功能,更改安全级别(从而允许访问受保护的页面,如Alexey的答案中所述)比更改安全级别更快以及整个虚拟内存映射,以及所有关联的TLB缓存刷新和其他涉及完整上下文切换的其他内容。 由于系统调用可能是相当频繁的事件,因此在Linux和其他许多地方进化的设计是尽量减少利用内核服务的开销,并将内核代码和(至少部分)数据映射到每个进程中那部分。

另外一个重要的原因是我们说内核在进程地址空间是内核可以访问CURRENT进程的用户代码/数据,即虚拟地址空间0〜3G。

对不起我的英文不好 我不是以英语为母语的人。

想象一下,如果内核没有映射到每个进程的地址空间,会发生什么情况。如果发生定时器中断,处理器会调用ISR例程(中断描述符表)。如果内核没有映射,那么IDT地址变为无效,从而导致三重故障。