首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

探索 Linux 内存模型(5)

探索 Linux 内存模型(5)

物理内存区域我已经向您展示了(32 位架构上的) Linux 内核按照 3:1 的比率来划分虚拟内存:3 GB 的虚拟内存用于用户空间,1 GB 的内存用于内核空间。内核代码及其数据结构都必须位于这 1 GB 的地址空间中,但是对于此地址空间而言,更大的消费者是物理地址的虚拟映射。
之所以出现这种问题,是因为若一段内存没有映射到自己的地址空间中,那么内核就不能操作这段内存。因此,内核可以处理的最大内存总量就是可以映射到内核的虚拟地址空间减去需要映射到内核代码本身上的空间。结果,一个基于 x86 的 Linux 系统最大可以使用略低于 1 GB 的物理内存。
为了迎合大量用户的需要,支持更多内存、提高性能,并建立一种独立于架构的内存描述方法,Linux 内存模型就必须进行改进。为了实现这些目标,新模型将内存划分成分配给每个 CPU 的空间。每个空间都称为一个 节点;每个节点都被划分成一些 区域。区域(表示内存中的范围)可以进一步划分为以下类型:
  • ZONE_DMA(0-16 MB):包含 ISA/PCI 设备需要的低端物理内存区域中的内存范围。
  • ZONE_NORMAL(16-896 MB):由内核直接映射到高端范围的物理内存的内存范围。所有的内核操作都只能使用这个内存区域来进行,因此这是对性能至关重要的区域。
  • ZONE_HIGHMEM(896 MB 以及更高的内存):系统中内核不能映像到的其他可用内存。
节点的概念在内核中是使用 struct pglist_data 结构来实现的。区域是使用 struct zone_struct 结构来描述的。物理页框是使用 struct Page 结构来表示的,所有这些 Struct 都保存在全局结构数组 struct mem_map 中,这个数组存储在 NORMAL_ZONE 的开头。节点、区域和页框之间的基本关系如图 9 所示。
图 9. 节点、区域和页框之间的关系当实现了对 Pentium II 的虚拟内存扩展的支持(在 32 位系统上使用 PAE —— Physical Address Extension —— 可以访问 64 GB 的内存)和对 4 GB 的物理内存(同样是在 32 位系统上)的支持时,高端内存区域就会出现在内核内存管理中了。这是在 x86 和 SPARC 平台上引用的一个概念。通常这 4 GB 的内存可以通过使用 kmap() 将 ZONE_HIGHMEM 映射到 ZONE_NORMAL 来进行访问。请注意在 32 位的架构上使用超过 16 GB 的内存是不明智的,即使启用了 PAE 也是如此。
(PAE 是 Intel 提供的内存地址扩展机制,它通过在宿主操作系统中使用 Address Windowing Extensions API 为应用程序提供支持,从而让处理器将可以用来寻址物理内存的位数从 32 位扩展为 36 位。)
这个物理内存区域的管理是通过一个 区域分配器(zone allocator) 实现的。它负责将内存划分为很多区域;它可以将每个区域作为一个分配单元使用。每个特定的分配请求都利用了一组区域,内核可以从这些位置按照从高到低的顺序来进行分配。
例如:
  • 对于某个用户页面的请求可以首先从“普通”区域中来满足(ZONE_NORMAL);
  • 如果失败,就从 ZONE_HIGHMEM 开始尝试;
  • 如果这也失败了,就从 ZONE_DMA 开始尝试。
这种分配的区域列表依次包括 ZONE_NORMAL、ZONE_HIGHMEM 和 ZONE_DMA 区域。另一方面,对于 DMA 页的请求可能只能从 DMA 区域中得到满足,因此这种请求的区域列表就只包含 DMA 区域。
结束语内存管理是一组非常庞大、复杂且耗时的任务,也是一个非常难以实现的任务,因为我们需要精雕细琢出一个模型,设计好系统如何在真实的多程序的环境中进行操作,这是一项非常艰难的工作。诸如调度、分页行为和多进程的交互组件都向我们提出了相当难度的挑战。我希望本文可以帮助您了解接受 Linux 内存管理挑战所需要的一些基本知识,并为您提供一个起点。
返回列表