
AI-摘要
Tianli GPT
AI初始化中...
介绍自己 🙈
生成本文简介 👋
推荐相关文章 📖
前往主页 🏠
前往爱发电购买
[linux内存管理] 第015篇 理解Linux内核中的memblock和ioremap机制
iliuqi0. 前言
Linux驱动开发中,设备寄存器的物理地址如何被内核管理并映射到虚拟地址空间,是一个非常核心的知识点。本文将从memblock
和ioremap
的机制入手,梳理相关流程和原理。
1. 什么是memblock?
memblock 是 Linux 内核在启动阶段管理物理内存的核心工具。它的主要作用是记录和管理物理内存的分布情况,并确保特定的物理地址范围不被错误分配。
memblock 的功能
- 内存管理:
- 记录系统中所有的物理内存块(memory)。
- 标记已分配或保留的内存块(reserved)。
- 设备寄存器保留:
-通过 memblock_reserve() 标记设备寄存器所在的物理地址范围为 reserved,防止这些地址被动态分配器(如 kmalloc())分配。 - 分配的时机:
- 引导阶段:在内核初始化期间使用,启动完成后交由更高级的内存管理器(如 buddy allocator)接管。
详细请查看:[linux内存管理] 第008篇 memblock子系统详解
2. 什么是ioremap?
ioremap 是 Linux 内核用于将物理地址映射到虚拟地址的函数。由于现代内核只能通过虚拟地址访问内存,设备寄存器的物理地址必须先映射到内核虚拟地址空间,驱动才能访问这些寄存器。
ioremap 的功能
- 物理到虚拟地址映射:
- 将一个指定的物理地址范围(如设备寄存器地址)映射到内核的虚拟地址空间。
- 设置缓存属性:
- 为映射的地址指定合适的缓存属性(如不可缓存、强制写入等),以确保设备操作的正确性。
- 动态虚拟地址分配:
- 分配一个新的虚拟地址范围,用于指向指定的物理地址。
3. memblock和ioremap的关系?
memblock 和 ioremap 是内核在不同阶段管理设备寄存器的两种机制:
阶段 | 作用 |
---|---|
内核引导阶段 | 使用 memblock 将设备寄存器的物理地址标记为 reserved,避免分配冲突。 |
驱动运行时 | 使用 ioremap 将这些物理地址映射到内核虚拟地址空间,驱动通过虚拟地址访问寄存器。 |
核心区别
memblock 的作用:
- 记录物理地址的分布,标记保留的地址范围。
- 只管理物理地址,不提供直接的访问能力。
ioremap 的作用:
- 将物理地址映射为虚拟地址。
- 驱动程序通过映射后的虚拟地址访问设备寄存器。
4. 设备寄存器映射的完整流程
以下是设备寄存器从物理地址到虚拟地址映射的完整流程:
4.1 设备描述
在设备树中定义设备寄存器的物理地址和大小:
1 | ipcc@208000 { |
4.2 内核启动阶段
- 解析设备树,通过 memblock_reserve() 将物理地址范围标记为 reserved。
- 确保这些地址不被普通内存分配器使用。
注意:此部分的内容,详细查看:[linux内存管理] 第008篇 memblock子系统详解
4.3 驱动加载
在设备驱动的 probe() 函数中,通过函数(如 platform_get_resource()
或 of_address_to_resource()
)获取设备的物理地址范围。
4.4 地址映射
使用 ioremap()
或其变体(如 of_iomap()
),将物理地址映射到内核虚拟地址空间
1 | void __iomem *base = ioremap(phys_addr, size); |
4.5 访问寄存器
映射完成后,驱动通过虚拟地址访问设备寄存器
1 | writel(value, base + offset); |
5. 总结
- memblock分配的是物理地址,在开机初期解析设备树中的节点,将内存分
reserved
和memory
两种类型来标记,确保不会这些地址的内存被当作普通内存分配使用 - ioremap是将物理地址映射到虚拟地址空间,MMU起来后,内核访问尽量都会使用虚拟地址来进行。
- memblock确保内存的安全性,ioremap实现实际的地址的访问能力。
评论
匿名评论隐私政策