上周认真学习了LDD3第15章直接内存访问部分,这周调试PCI的网卡和视频采集卡,结合代码对DMA映射有了进一步的理解,这里按照LDD315章的顺序总结一下,记一下笔记,以后忘了再来翻,本人刚毕业1年菜鸟,理解不到的地方还希望大神指点!
根据LDD3说法,DMA是一种硬件机制,是说硬件具有这种仲裁能力,在cpu不干预的情况下设备可以作为主设备来对内存的直接读写访问,这样可以大大提高大数据流的传输速度。我所调试的PCI网卡和视频采集卡就是支持DMA机制的设备。
在讲解内核提供的通用DMA层之前,LDD3介绍了底层直接来分配DMA缓冲的方法,当然这种方法在编写驱动的过程中是不提倡的,原因在LDD3的15.4.4通用DMA层有解释,主要是缓存一致性和可移植性的问题,但是学习底层直接分配DMA的方法对于我们理解DMA的工作原理还是有好处的,在通用DMA层之前有2个知识点需要记录:
1
LDD3说道“随 DMA 缓冲带来的主要问题是, 当它们大于一页, 它们必须占据物理内存的连续页因为设备使用 ISA 或者 PCI 系统总线传输数据, 它们都使用物理地址”。
这段话说明分配DMA缓冲区时必须是物理上连续的一段空间,原因我的理解是因为DMA是设备的一种机制,真正使用DMA的是设备,也就是说cpu分配好缓冲区给设备,设备来进行DMA操作,完成对缓冲区的访问,这个过程对cpu是不透明的,设备对缓冲区的寻址是物理地址,如果这个设备是挂载在PCI总线上,则设备对DMA缓冲区的寻址就是pci总线地址。这里还有2点需要说明,一是对于普通的具有DMA的设备,他们只能对物理上连续的地址进行访问,所以一般设备的DMA缓冲区必须物理连续,还有一类设备具有sgDMA的能力,这类设备的DMA缓冲区可以在物理上分散的。
2
在15.4.3一节中说明了总线地址,说明如下:
一个使用 DMA 的设备驱动必须和连接到接口总线的硬件通讯, 总线使用物理地址, 而程序代码使用虚拟地址.事实上, 情况比这个稍微有些复杂. 基于 DMA 的硬件使用总线地址, 而不是物理地址. 尽管 ISA 和 PCI 总线地址在 PC 上完全是物理地址, 这对每个平台却不总是真的. 有时接口总线被通过桥接电路连接, 它映射 I/O 地址到不同的物理地址. 一些系统甚至有一个页映射机制, 使任意的页连续出现在外设总线.
这一段话我刚开始看不是很理解,现在结合调试PCI总线设备的DMA,才算是想通,这段话主要涉及到3个地址:虚拟地址 物理地址 总线地址,只要把这3个地址区分开,这段话就可以理解了。
理解物理地址和虚拟地址还是比较简单的,虚拟地址是通过了操作系统内存管理单元映射之后的地址。物理地址是站在cpu角度看到的外设资源的地址。起初我把物理地址和总线地址混淆在一起,感觉物理地址就是总线地址,但是经过调试PCI网卡和视频卡的DMA才理解了这个问题,说清楚这个问题,首先要说清楚pci控制器的地址映射。
对于cpu来说,不管是设备直接挂接在cpu本地总线还是通过pci总线挂接,cpu去访问这个设备都是通过物理地址,这个物理地址就是本地总线的地址。pci总线上的设备需要将自己的资源映射到本地总线,