我读到前 3 GB 是为进程保留的,最后 GB 是为内核保留的。我还了解到内核是从物理地址空间的第 2 MB 开始加载的(取决于配置)。我的问题是,最后 1 GB 的映射对于所有进程来说都是相同的,并且映射到内存的这个物理区域?
另一个问题是,当进程切换到内核模式时(例如,当发生sys调用时),那么使用什么页表,进程页表还是内核页表?如果使用内核页表,则它们无法访问属于进程的内存位置。如果是这种情况,那么内核虚拟内存显然没有用处,因为对内核代码和数据的所有访问都将通过最后 1 GB 进程地址空间的映射。请帮我澄清这一点(任何有用的链接将不胜感激)
最佳答案
看来您正在谈论 32 位 x86 系统,对吗?
如果我没记错的话,内核不仅可以配置为 3Gb/1Gb 内存分配,还可能有其他变体(例如 2Gb/2Gb)。尽管如此,3Gb/1Gb 可能是 x86-32 上最常见的一种。
地址空间的内核部分应该无法从用户空间访问。从内核的角度来看,是的,内核本身占用的内存的映射总是相同的。无论如何,内核当前在哪个进程(或中断处理程序,或其他任何东西)的上下文中运行。
结果之一是,如果您从不同的进程查看 /proc/kallsyms
中的内核符号的地址,您每次都会看到相同的地址。从内核的角度来看,这些正是各个内核函数、变量等的地址。
所以我想,你的第一个问题的答案是"is",但它对于用户空间代码可能不是很有用,因为内核空间内存无论如何都不能直接访问。
对于第二个问题,如果内核当前在某个进程的上下文中运行,它实际上可以访问该进程的用户空间内存。我无法详细描述它,但内核函数 copy_from_user
和 copy_to_user
的实现可能会给您一些提示。请参阅内核源代码中的 arch/x86/lib/usercopy_32.c
和 arch/x86/include/asm/uaccess.h
。看起来,在 x86-32 上,用户空间内存是在这些函数中直接访问的,使用当前进程上下文的默认内存映射。那里的“神奇”东西只与优化和检查内存区域地址的正确性有关。
关于linux-kernel - Linux 进程地址空间中的最后 GB 是否映射到相同的物理内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6082385/