系列文章目录
提示:本系列主要记录工作过程中遇到的操作系统基础概念以及工作原理
- 第一章 操作系统之IOMMU
文章目录
- 系列文章目录
- 1. 设备访问内存的几种主要方式
- 1.1 传统的 I/O 访问(程序控制 I/O)
- 1.2 直接内存访问(DMA)
- 1.3 设备驱动与内存映射
- 2. IOMMU简介
- 3. IOMMU的作用
- 3.1 提高了内存安全性
- 3.2 解决 32 位设备的地址扩展问题
- 4. 总结
1. 设备访问内存的几种主要方式
1.1 传统的 I/O 访问(程序控制 I/O)
在最早的计算机系统中,设备通过 CPU 执行 I/O 操作来访问内存。这种方式也称为 程序控制 I/O。
操作方式
:设备通过 CPU 发起 I/O 请求,CPU 会根据程序中的指令,手动读取或写入内存。
例如,磁盘控制器向内存中写入数据时,CPU 会通过一系列指令来控制数据传输。缺点
:CPU 必须参与每次数据传输,这样不仅增加了 CPU 的负担,还导致了 CPU 的效率低下,因为它需要等待设备完成数据传输。这种方法效率低,尤其是在大量数据传输时。
1.2 直接内存访问(DMA)
DMA(Direct Memory Access) 是一种提高设备访问内存效率的方法
。
操作方式
:在 DMA 模式下,设备可以直接与内存进行数据交换,无需 CPU 参与数据传输过程。特点
:DMA模式下的关键硬件叫DMAC(Controller),我理解该硬件的诞生就是为了将设备访问内存时cpu的职责进行了析出,从而让cpu做其它更重要的事(毕竟cpu是万金油,啥都需要它)。
1.3 设备驱动与内存映射
在现代操作系统中,设备访问内存通常是通过设备驱动程序
进行的。驱动程序负责与硬件设备进行通信,并将设备的内存空间
映射到进程的虚拟地址空间
中。
操作方式
:驱动程序通过操作系统提供的接口将设备内存映射到用户空间或内核空间。当应用程序或操作系统需要访问设备时,它直接操作映射到内存中的数据。
这种方式通常用于高性能的 I/O 操作,如网络通信、显卡渲染等。
2. IOMMU简介
IOMMU(Input/Output Memory Management Unit)是内存控制器( memory controller)的一部分,用于将设备虚拟地址
(也可称为I/O地址或设备地址)转换为物理地址
。
IOMMU的概念类似于MMU(Memory Management Unit),区别在于:
IOMMU:将设备虚拟地址翻译为物理地址;
MMU:负责将CPU虚拟地址翻译为物理地址。
在设备做DMA访问内存的时候,系统返回给设备驱动的不再是物理地址,而是虚拟地址 ,这个地址一般叫IOVA
,设备访问内存时,由IOMMU来将这个设备虚拟地址
转换为物理地址。
从上图可知,IOMMU是DMA(直接内存访问,即设备与内存直接通信,而无需经过CPU)过程中的一个环节。1
因此IOMMU可以看作一种机制,也可以说:IOMMU是DMA的一种实现方式
。
3. IOMMU的作用
IOMMU的引人带来了哪些好处呢?
- 提高了内存安全性;
- 扩展设备地址访问范围;
3.1 提高了内存安全性
传统方式(设备直接访问物理地址),设备可能会访问到不属于自己的内存区域(例如:破坏操作系统的内存结构),造成数据泄漏或系统崩溃。
相反,基于IOMMU机制的DMA内存访问方式,IOMMU 可以在内存访问之前进行检查,确保设备只能访问其分配的内存区域,防止设备访问操作系统的核心数据结构或其他虚拟机的内存,这对于防止设备对其他虚拟机或操作系统内存的恶意或意外访问至关重要。
结论: IOMMU使得设备无法直接访问物理地址,大大增加了设备进行DMA攻击的难度。
3.2 解决 32 位设备的地址扩展问题
设备访问 4GB 以上内存的问题
:许多传统的设备(例如 32 位 DMA-capable 设备、网卡、硬盘控制器等)不能直接访问超过 4GB 的内存,因为它们只能使用 32 位的地址空间。但是,现代操作系统的内存往往大于4GB。
如果设备申请DMA(设备直接访问内存)时,内核为设备分配的DMA buffer地址高于4GB(简称为high buffer
),则设备将无法寻址到它。
IOMMU通过地址转换提供了解决方案
:IOMMU 需要提供一种间接方式,让设备能够通过低地址的缓冲区(low buffer)来与高地址的内存(high buffer)进行交互。这一过程通常被称为 “sync” 或 “bounce” 机制,具体过程如下:
-
设备请求访问高地址内存
:假设设备需要访问 4GB 以上的内存(high buffer),但设备无法直接寻址到高地址,因为它只能使用 32 位地址。 -
IOMMU 为设备分配低地址内存(low buffer)
:IOMMU 会为设备分配一个低于 4GB 的内存区域(low buffer),这块内存与高地址内存(high buffer)的大小一致。
设备会通过低地址缓冲区(low buffer)进行 DMA 操作。虽然设备只能访问 low buffer,但通过 IOMMU 的映射,它的请求会在后台被转换成访问高地址内存(high buffer)。 -
IOMMU 进行数据同步
:设备向低地址缓冲区(low buffer)写入数据后,IOMMU 会将 low buffer 中的数据复制到高地址缓冲区(high buffer)。反之,CPU 或其他系统组件向高地址缓冲区(high buffer)写入数据时,IOMMU 会将数据从 high buffer 复制到低地址缓冲区(low buffer)。 -
数据传递与同步
:通过这种方式,尽管设备无法直接访问超过 4GB 的内存,但它通过 low buffer 间接完成了数据读写。
结论:IOMMU 的“sync”或“bounce”机制确保了设备和 CPU 可以通过这两个内存区域交换数据,从而实现了高地址内存的间接访问。
4. 总结
本文主要介绍了设备访问内存的几种方式,以及IOMMU的基本概念、主要作用。
后续有时间再学习下虚拟化中IOMMU的作用2。
Linux x86-64 IOMMU详解(一)——IOMMU简介 ↩︎
linux内核中IOMMU 基础架构介绍 ↩︎