为什么linux内存要分DMA区域,常规区域和高端内存区域?

Linux内核划分内存区域主要是由于历史遗留问题和硬件架构的限制:

  1. DMA区域 (ZONE_DMA)

为什么存在:

· 早期ISA总线设备只能访问前16MB物理内存(24位地址总线限制)

· 某些老式DMA控制器只能访问前64KB或前16MB内存

· 确保这些老设备能够正常工作

用途:

· 分配给需要DMA操作的老式设备(声卡、网卡等)

· 防止这些设备因为无法访问内存而失败

  1. 常规区域 (ZONE_NORMAL)

为什么存在:

· 在32位系统中,内核虚拟地址空间有限(通常1GB)

· 这1GB空间需要直接映射到物理内存,称为线性映射或直接映射

· 这个直接映射区域就是ZONE_NORMAL

关键限制:

· 32位系统:内核空间1GB → 直接映射最大896MB

· 这896MB就是ZONE_NORMAL的大小

· 内核可以直接访问这个区域的物理内存,无需特殊映射

  1. 高端内存区域 (ZONE_HIGHMEM) - 32位系统的特殊产物

核心问题:

32位系统4GB虚拟地址空间分配:

复制代码
0-3GB:用户空间(每个进程独立)
3-4GB:内核空间(所有进程共享)

内核只有1GB虚拟地址空间,但物理内存可能超过1GB(如2GB、4GB)。

解决方案:

· ZONE_NORMAL(≤896MB):永久映射到内核虚拟地址空间

· ZONE_HIGHMEM(>896MB):动态映射到内核虚拟地址空间

高端内存访问机制:

c 复制代码
// 临时映射高端内存页面
void *kmap(struct page *page);
void kunmap(struct page *page);

// 原子映射(中断上下文可用)
void *kmap_atomic(struct page *page);
  1. 64位系统的变化

在64位系统中,情况完全不同:

关键优势:

· 虚拟地址空间极其巨大(x86_64:128TB内核空间)

· 内核可以将所有物理内存直接线性映射

· ZONE_HIGHMEM 不再需要(64位Linux中已移除)

现代64位系统的典型区域:

c 复制代码
// x86_64架构
ZONE_DMA      : 0-16MB     // 兼容老设备
ZONE_DMA32    : 16MB-4GB   // 32位DMA设备
ZONE_NORMAL   : 4GB-64TB   // 大部分内存都在这里
// 注意:没有ZONE_HIGHMEM!
  1. 各区域的物理位置

在32位系统(4GB物理内存)中:

复制代码
物理地址空间:
0-16MB    : ZONE_DMA      (DMA区域)
16-896MB  : ZONE_NORMAL   (常规区域)
896MB-4GB : ZONE_HIGHMEM  (高端内存)
          ↑
          └── 超过896MB的部分需要特殊映射
  1. 内存分配的优先级

内核分配内存时按顺序尝试:

  1. 先尝试在指定的ZONE分配
  2. 如果失败,按照fallback顺序尝试其他ZONE
  3. 例如:ZONE_HIGHMEM → ZONE_NORMAL → ZONE_DMA

总结表格

区域 32位系统 64位系统 主要用途

ZONE_DMA 0-16MB 0-16MB 老式DMA设备

ZONE_NORMAL 16-896MB 4GB以上 内核直接访问的内存

ZONE_HIGHMEM 896MB以上 不存在 动态映射的大内存(32位专用)

ZONE_DMA32 通常无 16MB-4GB 32位DMA设备

为什么保留这种设计?

  1. 向后兼容:支持老硬件和32位系统
  2. 性能优化:直接映射区域访问更快
  3. 资源管理:确保特殊设备有可用内存
  4. 简化移植:统一的接口,底层实现不同

关键启示:ZONE_HIGHMEM主要是32位时代的临时解决方案,64位系统已基本解决这个问题。但DMA区域仍然保留,确保老设备的兼容性。

相关推荐
心本无晴.1 天前
RAG技术详解:从原理到实战应用
开发语言·c#
qq_447429411 天前
Qwen Code CanUseTool 实现分析
linux·运维·服务器
The Sheep 20231 天前
可视化命中测试
java·服务器·前端
电科_银尘1 天前
【Python/Pytorch】-- 创建 tiny-cuda-nn 环境
开发语言·pytorch·python
wadesir1 天前
Ubuntu系统安装Miniconda完整指南
linux·运维·ubuntu
开开心心就好1 天前
右键菜单管理工具,添加程序自定义名称位置
linux·运维·服务器·ci/cd·docker·pdf·1024程序员节
郑泰科技1 天前
python虚拟环境实践:Conda 环境激活报错及解决
开发语言·python·conda
qq_310658511 天前
webrtc源码走读(六)核心引擎层——安全模块
服务器·c++·音视频·webrtc
j .1 天前
Java java.math.BigDecimal 类笔记
开发语言·python