为什么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 分钟前
Linux内核与驱动:9.驱动中的中断机制
linux
格林威3 分钟前
Windows 实时性补丁(RTX / WSL2)
linux·运维·人工智能·windows·数码相机·计算机视觉·工业相机
玖釉-4 分钟前
C++ 硬核剖析:if 语句中的“双竖杠” || 到底怎么运行的?
开发语言·c++
xuxie995 分钟前
N22 key驱动
linux·运维·服务器
大地的一角5 分钟前
(计算机网络)网络层原理与网络大致结构
服务器·网络·tcp/ip
满满和米兜6 分钟前
【Java基础】- 集合-HashSet与TreeSet
java·开发语言·算法
c++逐梦人13 分钟前
Linux多线程
linux·服务器
zhangzeyuaaa14 分钟前
Python推导式(Comprehensions)
开发语言·python
m0_7167652315 分钟前
数据结构三要素、时间复杂度计算详解
开发语言·数据结构·c++·经验分享·笔记·算法·visual studio
卷心菜狗16 分钟前
Python进阶基础--面向对象编程(OOP)
开发语言·python