看到很多 人在讨论 linux 内核 直接映射内存上限为什么是896M, 发现很多人都没有抓到要害,讨论之前澄清几个概念
userspace, 和 kernel space 空间划分 缺省是 userspace 0-3G, kernel space 3-4G
cpu 的寻址能力, 32位时候 是4GB 最大地址空间(真实的物理内存容量要低于这个,这个地址空间里面还有很多hole为acpi,bios,i/0 保留的)
第一个问题, 为什么内核要映射所有物理内存
首先虽然userspace 是0-3G 的地址空间, 但是这个实际上是虚拟的, userspace 进程无法直接去映射任何物理内存, 因为有很多进程在运行
每个进程都有0-3G的地址空间,所以每一个进程都有自己的页目录,切换的时候重新填cr3,来保证每个进程都有自己独立的物理页
但是分配真正的物理页给进程完全是靠内核去做的, 所以内核必须在内核空间控制所有的物理内存。简单说 0-3G是虚拟的有很多份
3-4G就一份。 如果不在3-4G 映射物理内存就无法保证0-3G的虚拟性,和既有的设计框架会有冲突。
比如如果一个物理页映射到0x80000000, 那么这个物理页就无法被内核所控制,os中跑10个进程就有10个0x80000000, 那么到底哪个映射到这个0x80000000
就完全无法判断。 实际的转化过程应该是 每个进程都有自己的0x80000000, 然后每个进程都有自己的页目录,所以每个独立的0x80000000都会映射到不同的物理页
第二个问题是为什么上限是896M
内核接管所有的物理内存,但是内核的地址空间只有1G, 那么最多也就是直接映射1G的物理内存到内核空间
而且这1G空间还要保留一些做其它用途,DMA etc
所以内核空间最多也无法映射1G的物理内存, 那么怎么办呢, 只好折中一下, 设定一个上限 HIGH_MEM
内存低于这个上限就全部直接映射, 高于这个上限 就把剩余部分间接映射。 那么这个上限是多少好呢,
linux的设计是896M 算是一个经验性的值吧,,大家都觉得这个比较合适。。