2

我读到前 3 GB 是为进程保留的,最后一个 GB 是为内核保留的。我还读到内核是从物理地址空间的第 2 MB 开始加载的(取决于配置)。我的问题是,所有进程的最后 1 GB 的映射是否相同,并映射到该物理内存区域?

另一个问题是,当进程切换到内核模式时(例如,发生系统调用时),那么使用哪些页表,是进程页表还是内核页表?如果使用内核页表,则它们无法访问属于该进程的内存位置。如果是这样,那么内核虚拟内存显然没有用处,因为对内核代码和数据的所有访问都将通过最后 1 GB 进程地址空间的映射。请帮助我澄清这一点(任何有用的链接将不胜感激)

4

2 回答 2

4

看来,您是在谈论 32 位 x86 系统,对吧?

如果我没记错的话,内核不仅可以配置为 3Gb/1Gb 内存分布,还可以有其他变体(例如 2Gb/2Gb)。尽管如此,3Gb/1Gb 可能是 x86-32 上最常见的一种。

地址空间的内核部分应该不能从用户空间访问。从内核的角度来看,是的,内核本身占用的内存的映射总是一样的。无论如何,内核当前在哪个进程(或中断处理程序,或其他)的上下文中运行。

作为结果之一,如果您查看/proc/kallsyms来自不同进程的内核符号的地址,您每次都会看到相同的地址。从内核的角度来看,这些正是各个内核函数、变量等的地址。

所以我想,你的第一个问题的答案是“是”,但它可能对用户空间代码不是很有用,因为内核空间内存无论如何都不能直接从那里访问。

至于第二个问题,好吧,如果内核当前在某个进程的上下文中运行,它实际上可以访问该进程的用户空间内存。我无法详细描述它,但可能是内核函数的实现,copy_from_user可以copy_to_user给你一些提示。请参阅内核源代码中的arch/x86/lib/usercopy_32.carch/x86/include/asm/uaccess.h。看来,在 x86-32 上,用户空间内存是在这些函数中直接访问的,使用当前进程上下文的默认内存映射。那里的“神奇”东西只与优化和检查内存区域地址的正确性有关。

于 2011-05-21T20:50:14.543 回答
2

是的,内核部分地址空间的映射在所有进程中都是一样的。 它的一部分确实映射了加载内核映像的那部分物理内存,但这不是它的大部分——其余部分用于映射内核运行时工作集的其他物理内存位置。

当进程切换到内核模式时,页表不会改变。地址空间的内核部分变得可访问,因为 CPL(当前特权级别)现在为零。

于 2011-05-23T07:11:10.893 回答