ioremap / ioremap_wc / ioremap_cache / vmap / kmap 对比

2025-09-25 102 0

1. 功能概览

接口 作用对象 功能 虚拟地址属性
ioremap() 设备物理地址(MMIO) 把 I/O 物理地址映射到内核虚拟地址 非缓存(UC,Uncached)
ioremap_wc() 设备物理地址(显存、帧缓冲) 把 I/O 物理地址映射到内核虚拟地址 写合并(WC,Write-Combining)
ioremap_cache() 设备物理地址(支持 cache 的设备内存) 把 I/O 物理地址映射到内核虚拟地址 可缓存(WB,Write-Back)
vmap() 一组系统内存页 将离散的物理页映射到一块连续的虚拟地址 可缓存(WB)
kmap()/kmap_atomic() 单个高端内存页 临时把一个物理页映射到低端内核虚拟地址供 CPU 访问 可缓存(WB)

2. 主要区别

对比项 ioremap / ioremap_wc / ioremap_cache vmap kmap
输入对象 物理地址区间(通常来自设备 BAR、显存、MMIO) struct page * 数组 单个 struct page *
映射范围 可以映射大块连续物理地址 可以把离散页拼成连续虚拟区 一次只能映射一页
返回地址类型 void __iomem *(需要 readl/writel 等 I/O 访问) 普通内核指针,直接解引用 普通内核指针,直接解引用
缓存属性控制 可选择 UC/WC/WB 固定 WB(系统内存) 固定 WB(系统内存)
典型用途 访问设备寄存器、显存、DMA 缓冲区 文件系统、驱动将分散页拼成连续虚拟区 内核访问高端内存页(ZONE_HIGHMEM)
开销 分配 vmalloc 区域 + 建页表 + PAT/MTRR 设置 分配 vmalloc 区域 + 建页表 直接映射到固定 kmap 槽,开销小
能否用于设备地址 ✅ 是(专用) ❌ 否(只能映射系统 RAM) ❌ 否(只能映射系统 RAM)

3. 典型使用场景示例

ioremap()

用于访问设备寄存器(PCI BAR),避免 CPU cache 导致寄存器读写出错。

void __iomem *regs = ioremap(pci_resource_start(pdev, 0), len);
val = readl(regs + OFFSET);
writel(val, regs + OFFSET);

ioremap_wc()

用于映射显存帧缓冲,提高写入吞吐量。

void __iomem *fb = ioremap_wc(fb_phys_addr, fb_size);
memset_io(fb, 0xff, fb_size);  // 用写合并提升性能

ioremap_cache()

用于支持 cache 的设备 RAM,比如一些共享内存设备。

void __iomem *buf = ioremap_cache(dev_phys_mem, size);
memcpy_toio(buf, src, size);

vmap()

将分散的 page 映射成一块连续虚拟地址供内核访问。

struct page *pages[n];
void *vaddr = vmap(pages, n, VM_MAP, PAGE_KERNEL);
memset(vaddr, 0, n * PAGE_SIZE);

kmap() / kmap_atomic()

用于临时访问高端内存页。

void *vaddr = kmap(page);
do_something(vaddr);
kunmap(page);
  1. 直观示意图
物理地址空间:
+-----------+-----------------+-------------+
| 系统 RAM  | 设备寄存器/MMIO | 显存/外设RAM|
+-----------+-----------------+-------------+

内核虚拟地址空间:
+-----------+--------------------------------+-------------------+
| 直接映射  | vmalloc/ioremap 区 (ioremap/vmap)| kmap 区 (高端页映射)|
+-----------+--------------------------------+-------------------+
        ^               ^                  ^
        |               |                  |
   普通RAM映射     ioremap/vmap映射       kmap单页临时映射
  1. 记忆口诀

ioremap*:映射设备物理地址,能控制缓存属性,返回 __iomem 指针。

vmap:映射已有的普通物理页,拼成连续虚拟区。

kmap:映射单个物理页,主要给高端内存用。

相关文章

发布评论