Linux内核中的fixmap
和memblock
是两个不同层次的内存管理机制,分别用于不同的场景和阶段。以下是它们的核心区别和联系:
- 功能与作用
memblock
- 物理内存管理:
memblock
是内核启动早期的物理内存分配器,在伙伴系统(Buddy System)和slab分配器初始化之前使用。它的主要职责是:- 跟踪物理内存的可用区域(如从BIOS或设备树获取的内存信息)。
- 保留内存(如内核代码、设备保留内存、initrd等)。
- 分配物理内存给早期启动阶段的内核组件。
- 临时性:
一旦更高级的内存管理机制(如伙伴系统)初始化完成,memblock
会被弃用。
fixmap
- 虚拟地址映射:
fixmap
是一组预定义的虚拟地址,用于在内核启动阶段(页表未完全建立时)快速映射物理内存或设备寄存器。它的主要用途包括:- 访问硬件(如早期控制台、ACPI表)。
- 临时映射页表(如
early_ioremap
)。 - 内核启动阶段的内存操作(如解压initrd)。
- 持久性:
fixmap
的某些映射在内核运行期间长期存在(如固定映射的硬件寄存器)。
- 管理层次
- memblock:
直接管理物理内存,记录哪些区域是空闲的、已分配的或保留的。 - fixmap:
管理虚拟地址空间,提供一种机制将固定的虚拟地址映射到任意的物理地址(或设备寄存器)。
- 使用阶段
- memblock:
仅在启动早期(start_kernel
之前)使用,直到伙伴系统接管。 - fixmap:
在启动早期和内核运行期间均可能使用。例如:- 启动阶段:映射设备寄存器、解压内核镜像。
- 运行阶段:某些硬件(如ARM的
kmap_atomic
)可能依赖固定映射。
- 生命周期
- memblock:
初始化后逐步将内存信息迁移到伙伴系统,最终自身被废弃。 - fixmap:
内核运行期间始终存在,属于内核页表的一部分。
- 示例场景
memblock的典型使用
- 保留内核代码和数据占用的物理内存。
- 分配内存给
initrd
或设备树(DTB)。 - 标记不可用的内存区域(如硬件保留内存)。
fixmap的典型使用
- 映射早期控制台(如UART)的寄存器,用于打印调试信息。
- 在内核解压阶段映射压缩的镜像。
- 访问ACPI表或设备配置空间(如PCIe)。
总结
特性 memblock fixmap
管理对象 物理内存 虚拟地址映射
主要目的 跟踪和分配物理内存 提供固定虚拟地址映射
使用阶段 启动早期(伙伴系统初始化前) 启动早期 + 内核运行期间(部分映射)
持久性 临时,最终被替代 长期存在
依赖关系 不依赖页表 依赖内核页表配置
两者在启动过程中协作:memblock
负责分配物理内存,而fixmap
为这些内存或硬件提供虚拟地址映射,使内核能够在页表未完全建立时访问关键资源。