一个新手问题.我正在进行一些内核研究,并对ZONE_NORMAL的896MB大小限制感到困惑.我不明白为什么内核无法直接将4G物理内存映射到内核空间.一些文档提到了页面映射的大小限制.但考虑到4G内存有2 ^ 20页,每个"struct page"是4个字节,mem_map只有4MB.这应该不是问题.希望你能给我一些启示.
谢谢
内核将自身限制为896兆字节的原因是出于性能原因.
内核可用空间越多意味着用户空间可用的地址空间越少.这种3/1分割意味着用户进程可以分配的最大地址空间是3千兆字节 - 当然,由于内存碎片,实际上它似乎开始失败大约2.5千兆字节.
可以使用不同的拆分:2/2和1/3拆分,为内核分配2 GB的地址空间,为用户空间分配2 GB,为内核分配3 GB,为用户空间分配1 GB的地址空间.(这firefox是现在消耗1249兆字节,因此它可能不适合那些1/3分割的内核中的一个.)
有一些内核(可能只供应商?)支持所谓的4:4分割 - 内核的4千兆字节地址空间和用户空间的4千兆字节地址空间.这些对于具有32或64千兆字节内存的32位系统非常有用 - 因为大型系统可能有许多磁盘,飞行中有大量IO,并且需要对块设备和网络流量进行大量缓冲.但是,这些4:4内核需要在进入和退出每个系统调用时刷新TLB缓存.这些TLB刷新引入了"小"系统的显着减速,并且仅在"大型"系统上是值得的,其中额外的存储器可以缓存足够的磁盘/网络资源以改善系统的性能.
其他拆分不会导致此TLB刷新,因为TLB维护一个权限位,指示当CPU处于用户状态或管理程序状态时页面是否可用:内核页面始终映射,但仅在CPU的管理程序标志时标记为可用已设定.因此,当退出进入内核的进程时,进入和退出内核的速度很快.当上下文切换时,当然需要刷新TLB.
当然,内核可以映射所有可用内存.
在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中的内核虚拟地址不会直接映射到物理内存.这留下最多896 MB ZONE_NORMAL.因此,即使一个拥有1 GB的物理RAM,实际上只有896 MB可用于用户空间.
为了更好地理解这个主题,我建议你看一下Linux设备驱动程序的第15章(pdf).