当前位置: 首页 > news >正文

MMIO 映射

MMIO(Memory-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 级)仅 64KB(0–0xFFFF)
缓存 / 优化可设 WC、可复用 MMU / 页表无缓存、无优化
典型架构ARM/RISC 全用;x86 主流x86 遗留、嵌入式少量用

硬件:地址分配(BAR)

PCI/PCIe 设备用BAR(Base 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 位readbioread8
16 位readwioread16
32 位readlioread32
64 位readqioread64

写操作:

  • writebiowrite8
  • writewiowrite16
  • writeliowrite32
  • writeqiowrite64

关键技术点

  • MMU 作用:内核虚拟地址 → 设备物理地址;用户态不可直接访问(保护)。
  • IOMMU:设备 DMA 地址重映射、隔离、防越界(虚拟化 / 安全)。
  • 虚拟化:VM 访问 MMIO 触发 VM-Exit,由 QEMU/KVM 模拟设备行为。
  • 典型场景:网卡、GPU、NVMe、USB 控制器、嵌入式 GPIO/UART/SPI 等。

IOMMU与MMIO

IOMMU 与 MMIO 是两个完全不同但紧密配合的底层硬件机制

  • MMIO:CPU 用普通访存指令访问设备寄存器(CPU→设备控制通路)。
  • IOMMU:硬件地址转换单元,管控设备 DMA 访问内存(设备→内存数据通路)。

MMIO(Memory-Mapped I/O)

CPU 访问设备寄存器的方式

  • 设备寄存器(控制 / 状态)被映射到CPU 物理地址空间(PCIe BAR 分配)。
  • CPU 用ioread32/iowrite32readl/writel)读写这些地址。
  • 不经过 IOMMU:总线直接路由到设备,不做地址转换。

典型流程(CPU 配置设备)

  1. PCIe 枚举 → 分配 MMIO 物理地址(BAR)
  2. 驱动ioremap→ 内核虚拟地址
  3. iowrite32写寄存器 → 配置 DMA、启动传输

IOMMU(Input–Output Memory Management Unit)

设备 DMA 访问内存的 “硬件防火墙 + 地址转换器”

  • 服务对象:DMA 设备(网卡、GPU、NVMe、存储控制器)
  • 核心功能:
    • 地址转换:设备 IOVA → 物理地址(或 GPA → HPA 虚拟化)
    • 隔离保护:设备只能访问授权内存,防止越界 / 恶意 DMA
    • 突破地址位宽限制:让 32/40 位设备访问全部内存

关键概念

  • IOVA:I/O Virtual Address,设备视角的 “虚拟地址”
  • I/O 页表:每个设备 / 域独立,内核动态管理
  • IOTLB:IOMMU 的 TLB 缓存

核心区别

维度MMIOIOMMU
作用CPU ↔ 设备寄存器(控制)设备 DMA → 内存(数据)
地址CPU 物理地址(BAR)设备 IOVA / GPA → HPA
触发CPUload/store设备主动 DMA 请求
转换无(直接路由)硬件地址转换
缓存Uncached / WC(设备寄存器)不缓存内存,只转换地址
内核接口ioremap/ioread32dma_map_*/iommu_domain

MMIO + IOMMU 完整协作流程(网卡发送)

  1. CPU 准备数据
    • 应用 → 用户虚拟地址 →MMU→ 物理地址
  2. CPU 用 MMIO 配置网卡
    • ioremap映射网卡 MMIO 基址
    • iowrite32写 DMA 基地址 / 长度 / 控制寄存器
    • 这里:MMIO 不经过 IOMMU
  3. CPU 触发 DMA(MMIO)
    • 写 “启动” 寄存器 → 网卡发起 DMA
  4. IOMMU 拦截并转换 DMA
    • 网卡发出:设备地址(IOVA/GPA)
    • IOMMU 查页表 →物理地址(HPA)
    • 权限检查 → 放行 / 报错
  5. DMA 完成 → 中断
    • 中断经 IOMMU 重映射(可选)
  6. CPU 读状态(MMIO)
    • ioread32查寄存器 → 确认完成

虚拟化关键

  • 虚拟机 MMIO:VM-Exit → QEMU 模拟
  • 设备直通(VT-d/AMD-Vi):IOMMU 转换 DMA,MMIO 直接透传或半模拟

总结

MMIO 是现代系统CPU↔设备通信的基石:统一地址、简化指令、支持高性能 DMA、便于虚拟化与安全隔离。驱动开发核心是:申请资源 → ioremap → ioread/iowrite → 释放

http://www.jsqmd.com/news/641735/

相关文章:

  • 揭秘!高就业率美容培训学校大起底、正规美容培训机构?看这一篇就够了! - 品牌测评鉴赏家
  • IndexTTS2 V23新手入门:手把手教你搭建本地语音合成系统
  • 收藏!小白/程序员必看:大模型在工业控制(PLC、变频器)中的应用与前景
  • 【SCI复现】基于纳什博弈和ADMM的多微网主体能源共享研究附Matlab代码
  • 重装系统后第一件事:快速恢复Youtu-VL-4B-Instruct-GGUF开发环境
  • CANoe DoIP测试避坑指南:从ETH不通到诊断层配置,我踩过的那些雷
  • 郑州美甲培训学校推荐|零基础必看!避坑不花冤枉钱,指尖搞钱攻略藏不住了 - 品牌测评鉴赏家
  • Nunchaku FLUX.1-dev惊艳案例:城市夜景+超写实材质+8K细节生成展示
  • 收藏!程序员小白必看:向量数据库VS知识图谱,大模型问答系统怎么选?
  • CTF实战解析——从bugkuCTF网站被黑看后门漏洞的发现与利用
  • 4月14日成都地区攀钢产开平板(Q235B;厚度5.75-15.75mm)现货报价 - 四川盛世钢联营销中心
  • 在北京学陪诊师考证在哪报名?守嘉陪诊解锁正规考证就业新路径 - 品牌排行榜单
  • 为什么92%的L4自动驾驶项目卡在多模态对齐?:从BEV+Transformer到端到端决策链的7层技术断点拆解
  • Xilinx程序固化避坑指南:为什么你的FSBL编译总失败?从工程配置到Flash烧录全解析
  • 本科生论文写作新选择:百考通AI实战指南,告别熬夜与低效
  • 20260413 if while 语句
  • Python3.7.8安装指南:从下载到环境配置的完整流程
  • 零基础学化妆|3家靠谱培训学校实测!小白闭眼冲不踩坑 - 品牌测评鉴赏家
  • 为什么90%的AI团队还在用“伪元学习”?:SITS2026闭门报告首次公开元学习能力成熟度评估矩阵(含自测工具包)
  • 电竞椅哪个牌子质量好?傲风M6Pro,告诉你什么是“开挂式”舒适
  • 昆明美甲培训怎么选不踩坑?4家正规机构实测推荐,零基础/就业/创业全覆盖 - 品牌测评鉴赏家
  • 像素时装锻造坊应用场景:独立电影概念设计中的像素化分镜草图生成
  • 美妆小白必看!揭秘专业化妆培训学校如何选 - 品牌测评鉴赏家
  • 模仿学习不是“抄动作”,而是重建认知链——AIAgent中意图-动作-反馈三元耦合机制(仅限头部AI团队内部使用的建模框架)
  • 从零搭建LuckFox RK3576嵌入式开发环境:一站式工具链配置指南
  • I2C协议 - 优雅的代价:深入开漏总线、时钟延展与多主仲裁的脆弱平衡
  • 高胜率却总亏光盈利?投资者如何避开马丁策略的风控盲区
  • 实测不踩坑|2026美甲培训机构TOP5推荐,零基础/创业者直接抄作业 - 品牌测评鉴赏家
  • 答辩PPT救星!百考通AI助你30分钟高效搞定,告别熬夜
  • 小程序不同方式获取参数