一个新手问题。我正在做一些内核研究,并对此感到困惑 ZONE_NORMAL的大小限制为896MB。我不明白为什么内核不能 将4G物理内存直接映射到内核空间。一些文件 提到了页面图的大小限制。但考虑到4G内存 有2 ^ 20页,每个“struct page”是4个字节,mem_map会 只有4MB。这应该不是问题。希望你能给我一些帮助 光。
由于
答案 0 :(得分:8)
内核将自身限制为896兆字节的原因是出于性能原因。
内核可用空间越多,意味着用户空间可用的 less 地址空间。这种3/1分割意味着用户进程可以分配的大部分地址空间是3千兆字节 - 当然,由于内存碎片,实际上它似乎开始失败大约2.5千兆字节。
可以使用不同的拆分:2/2和1/3拆分,为内核分配2 GB的地址空间,为用户空间分配2 GB,为内核分配3 GB,为用户空间分配1 GB的地址空间。 (此firefox
现在消耗1249兆字节,因此无法适应这些1/3拆分内核中的一个。)
有一些内核(可能只供应商?)支持所谓的4:4分割 - 内核的4 GB地址空间和用户空间的4 GB地址空间。这些对于具有32或64千兆字节内存的32位系统非常有用 - 因为大型系统可能有许多磁盘,飞行中有大量IO,并且需要对块设备和网络流量进行大量缓冲。但是,这些4:4内核需要在进入和退出每个系统调用时刷新TLB缓存。这些TLB刷新引入了“小”系统的显着减速,仅在“大型”系统上是值得的,额外内存可以缓存足够的磁盘/网络资源以提高系统性能。
其他拆分不会导致此TLB刷新,因为TLB维护一个权限位,指示当CPU处于用户状态或管理程序状态时页面是否可用:内核页面始终映射,但仅在CPU的管理员标志已设置。因此,当退出进入内核的进程时,进入和退出内核的速度很快。当上下文切换时,当然需要刷新TLB。
答案 1 :(得分:7)
当然,内核可以映射所有可用内存。
在Linux中,所有银行提供的内存都分为“节点”。这些节点用于指示每个存储区有多少内存。每个节点中的内存分为“区域”。目前定义的区域为ZONE_DMA
,ZONE_NORMAL
和ZONE_HIGHMEM
。
ZONE_DMA
进行数据传输,并将其映射到较低的物理内存范围(最大16 MB)。
ZONE_NORMAL
区域中的内存由内核在线性地址空间的上部区域映射。大多数操作只能在ZONE_NORMAL
进行;所以这是性能最关键的区域。 ZONE_NORMAL
从16 MB增加到896 MB。
为什么?
内存部分保留用于存储有关内存映射和页表的信息的内核数据结构。这在x86上是128 MB。因此,在内核可以访问的1 GB物理内存中(在典型配置中,1GB是为内核保留的),保留128MB。因此,此128 MB中的内核虚拟地址不会直接映射到物理内存。这为ZONE_NORMAL
留下了最多896 MB的空间。因此,即使一个拥有1 GB的物理RAM,实际上只有896 MB可用于用户空间。
为了更好地理解这个主题,我建议你看一下Linux设备驱动程序的第15章(pdf)。