rd640-酷狗2011官方下载
![内存缓冲区](/uploads/image/0895.jpg)
2023年4月3日发(作者:ie8)
单cpu中内存仲裁器的作用
驱动DMA工作
所有的PC都包含一个称为直接内存访问控制器或DMAC的辅助处理器,它
可以用来控制在RAM和I/O设备之间数据的传送。DMAC一旦被CPU激活,就可
以自行传送数据;当数据传送完成之后,DMAC发出一个中断请求。当CPU和
DMAC同时访问同一内存单元时,所产生的冲突由一个称为内存仲裁器的硬件电
路来解决。
使用DMAC最多的是磁盘驱动器和其他需要一次传送大量字节的慢速设备。
因为DMAC的设置时间相当长,所以在传送数量很少的数据时直接使用CPU效率
更高。
原来的ISA总线所使用的第一个DMAC非常复杂,难于对其进行编程。PCI
和SCSI总线所使用的最新DMAC依靠总线中的专用硬件电路,这就使设备驱动
程序开发人员的开发工作变得简单。
到现在为止,我们已区分了三类内存地址:逻辑地址、线性地址以及物理
地址,前两个在CPU内部使用,最后一个是CPU从物理上驱动数据总线所用的
内存地址。但是,还有第四种内存地址,称为总线地址:它是除CPU之外的硬
件设备驱动数据总线所用的内存地址。在PC体系结构中,总线地址和物理地址
是一致的;但是在其他体系结构中,例如Sun的SPARC和Compaq的Alpha体系
结构中,这两种地址是不同的。
从根本上说,内核为什么应该关心总线地址呢?这是因为在DMA操作中数据
传送不用CPU的参与:I/O设备和DMAC直接驱动数据总线。因此,在内核开始
DMA操作时,必须把所涉及的内存缓冲区总线地址或写入DMAC适当的I/O端口、
或写入I/O设备适当的I/O端口。
很多I/O驱动程序都使用直接内存访问控制器(DMAC)来加快操作的速度。
DMAC与设备的I/O控制器相互作用共同实现数据传送;后文中我们还会看到,
内核中包含一组易用的例程来对DMAC进行编程。当数据传送完成时,I/O控制
器通过IRQ向CPU发出信号。
当设备驱动程序为某个I/O设备建立DMA操作时,必须使用总线地址指定
所用的内存缓冲区。内核提供两个宏virt_to_bus和bus_to_virt,分别把虚
拟地址转换成总线地址或把总线地址转换成虚拟地址。
与IRQ一样,DMAC也是一种资源,必须把这种资源动态地分配给需要它的
设备驱动程序。驱动程序开始和结束DMA操作的方法依赖于总线的类型。
总线的DMA
每个ISADMAC只能控制有限个通道。每个通道都包括一组独立的内部寄存
器,所以,DMAC就可以同时控制几个数据的传送。
设备驱动程序通常使用下面的方式来申请和释放ISADMAC。设备驱动程序
照样要靠一个引用计数器来检测什么时候任何进程都不再访问设备文件。驱动
程序执行以下操作:
(1)在设备文件的open()方法中把设备的引用计数器加1。如果原来的值是
0,那么,驱动程序执行以下操作:
·调用request_irq()来分配ISADMAC所使用的IRQ中断号
·调用request_dma()来分配DMA通道
·通知硬件设备应该使用DMA并产生中断
·如果需要,为DMA缓冲区分配一个存储区域
(2)当必须启动DMA操作时,在设备文件的read()和write()方法执行以下
操作:
·调用set_dma_mode()把通道设置成读/写模式。
·调用set_dma_addr()来设置DMA缓冲区的总线地址。(因为只有最低的
24位地址会发给DMAC,所以缓冲区必须在RAM的前16MB中。)
·调用set_dma_count()来设置要发送的字节数。
·调用set_dma_dma()来启用DMA通道。
·把当前进程加入该设备的等待队列,并把它挂起。当DMAC完成数据传送
操作时,设备的I/O控制器就发出一个中断,相应的中断处理程序会唤醒正在
睡眠的进程。
·进程一旦被唤醒,就立即调用disable_dma()来禁用这个DMA通道。
·调用get_dma_residue()来检查是否所有的数据都已被传送。
(3)在设备文件的release方法中,减少设备的引用计数器。如果该值变成
0,就执行以下操作:
·禁用DMA和对这个硬件设备上的相应中断
·调用free_dma()来释放DMA通道
·调用free_irq()来释放DMA所使用的IRQ线
总线的DMAPCI总线对于DMA的使用要简单得多,因为DMAC是集成
到I/O接口内部的。在open方法中,设备驱动程序照样必须分配一条IRQ线来
通知DMA操作的完成。但是,并没有必要分配一个DMA通道,因为每个硬件设
备都直接控制PCI总线的电信号。要启动DMA操作,设备驱动程序在硬件设备
的某个I/O端口中简单地写入DMA缓冲区的总线地址、传送方向以及数据大小;
然后驱动程序就挂起当前进程。在最后一个进程关闭这个文件对象时,release
方法负责释放这条IRQ线。
更多推荐
内存缓冲区
发布评论