MMIO 映射

张开发
2026/4/14 22:43:34 15 分钟阅读

分享文章

MMIO 映射
MMIOMemory-Mapped I/O内存映射 I/O是将硬件设备的寄存器、片上内存映射到 CPU 统一物理地址空间CPU 用普通load/store指令访问设备的主流通信机制。核心原理地址统一设备寄存器占用一段物理地址如 PCIe BAR 分配与内存共用地址总线。指令复用无需in/out等专用 I/O 指令直接用mov/ldr/str访问。硬件路由总线控制器、桥片识别 MMIO 地址转发到设备而非 DRAM。缓存属性寄存器区通常非缓存Uncached、禁止预取显存等可用Write-Combining (WC)。MMIO vs PIO端口映射 I/O特性MMIOPIO (Port I/O)地址空间与内存共享物理地址空间独立 64KB I/O 空间x86访问指令普通 load/store专用in/out系列地址大小可很大GB 级仅 64KB0–0xFFFF缓存 / 优化可设 WC、可复用 MMU / 页表无缓存、无优化典型架构ARM/RISC 全用x86 主流x86 遗留、嵌入式少量用硬件地址分配BARPCI/PCIe 设备用BARBase Address Register向系统声明物理基址、长度、类型32/64bit可预取Prefetchable适合显存、FIFO允许聚合写不可有序列表预取Non-Prefetchable适合控制 / 状态寄存器必须严格序、不缓存Linux 内核映射流程驱动资源申请// 检查并占用MMIO物理区间 request_mem_region(phys_addr, size, my_dev);物理→内核虚拟地址映射// 基础非缓存、设备映射 void __iomem *io_base ioremap(phys_addr, size); // 推荐设备模型托管、自动释放 void __iomem *io_base devm_ioremap_resource(dev, res);安全访问必须用内核宏// 读 u32 val ioread32(io_base REG_OFFSET); // 写 iowrite32(0x1, io_base REG_CTRL);禁止直接*(u32*)io_base跨架构、字节序、缓存问题必要时加内存屏障mb()/wmb()/rmb()保证访问序注销映射iounmap(io_base); release_mem_region(phys_addr, size);io读写接口readl老接口x86/ARM 早期用得多不跨平台。ioread32标准现代接口Linux 官方推荐所有架构通用。内核驱动规范优先用 ioread32 /iowrite32。在内核里很多平台上 ioread32 就是直接调用 readl#define ioread32(a) readl(a)但规范上必须用 ioread32保证未来不报错、不废弃。平台兼容性readl只适配部分架构x86 / ARM在 RISC-V、PowerPC 等可能不兼容。ioread32Linux 通用 I/O 访问接口所有架构都支持。字节序处理MMIO 寄存器都是小端 / 设备端内核会自动处理readl简单转换ioread32标准、安全、统一的字节序转换对应关系表宽度老接口现代标准接口8 位readbioread816 位readwioread1632 位readlioread3264 位readqioread64写操作writeb→iowrite8writew→iowrite16writel→iowrite32writeq→iowrite64关键技术点MMU 作用内核虚拟地址 → 设备物理地址用户态不可直接访问保护。IOMMU设备 DMA 地址重映射、隔离、防越界虚拟化 / 安全。虚拟化VM 访问 MMIO 触发 VM-Exit由 QEMU/KVM 模拟设备行为。典型场景网卡、GPU、NVMe、USB 控制器、嵌入式 GPIO/UART/SPI 等。IOMMU与MMIOIOMMU 与 MMIO 是两个完全不同但紧密配合的底层硬件机制MMIOCPU 用普通访存指令访问设备寄存器CPU→设备控制通路。IOMMU硬件地址转换单元管控设备 DMA 访问内存设备→内存数据通路。MMIOMemory-Mapped I/OCPU 访问设备寄存器的方式设备寄存器控制 / 状态被映射到CPU 物理地址空间PCIe BAR 分配。CPU 用ioread32/iowrite32readl/writel读写这些地址。不经过 IOMMU总线直接路由到设备不做地址转换。典型流程CPU 配置设备PCIe 枚举 → 分配 MMIO 物理地址BAR驱动ioremap→ 内核虚拟地址iowrite32写寄存器 → 配置 DMA、启动传输IOMMUInput–Output Memory Management Unit设备 DMA 访问内存的 “硬件防火墙 地址转换器”服务对象DMA 设备网卡、GPU、NVMe、存储控制器核心功能地址转换设备 IOVA → 物理地址或 GPA → HPA 虚拟化隔离保护设备只能访问授权内存防止越界 / 恶意 DMA突破地址位宽限制让 32/40 位设备访问全部内存关键概念IOVAI/O Virtual Address设备视角的 “虚拟地址”I/O 页表每个设备 / 域独立内核动态管理IOTLBIOMMU 的 TLB 缓存核心区别维度MMIOIOMMU作用CPU ↔ 设备寄存器控制设备 DMA → 内存数据地址CPU 物理地址BAR设备 IOVA / GPA → HPA触发CPUload/store设备主动 DMA 请求转换无直接路由硬件地址转换缓存Uncached / WC设备寄存器不缓存内存只转换地址内核接口ioremap/ioread32dma_map_*/iommu_domainMMIO IOMMU 完整协作流程网卡发送CPU 准备数据应用 → 用户虚拟地址 →MMU→ 物理地址CPU 用 MMIO 配置网卡ioremap映射网卡 MMIO 基址iowrite32写 DMA 基地址 / 长度 / 控制寄存器这里MMIO 不经过 IOMMUCPU 触发 DMAMMIO写 “启动” 寄存器 → 网卡发起 DMAIOMMU 拦截并转换 DMA网卡发出设备地址IOVA/GPAIOMMU 查页表 →物理地址HPA权限检查 → 放行 / 报错DMA 完成 → 中断中断经 IOMMU 重映射可选CPU 读状态MMIOioread32查寄存器 → 确认完成虚拟化关键虚拟机 MMIOVM-Exit → QEMU 模拟设备直通VT-d/AMD-ViIOMMU 转换 DMAMMIO 直接透传或半模拟总结MMIO 是现代系统CPU↔设备通信的基石统一地址、简化指令、支持高性能 DMA、便于虚拟化与安全隔离。驱动开发核心是申请资源 → ioremap → ioread/iowrite → 释放。

更多文章