DMA摘录

系统, 网卡, DMA连通的形式
Data transfer can be triggered in two ways: either the software asks for data (via a function such as read) or the hardware asynchronously pushes data to the system.
In the first case, the steps involved can be summarized as follows:

  1. When a process calls read, the driver method allocates a DMA buffer and instructs the hardware to transfer its data into that buffer. The process is put to sleep.
  2. The hardware writes data to the DMA buffer and raises an interrupt when it’s done.
  3. The interrupt handler gets the input data, acknowledges the interrupt, and awakens the process, which is now able to read data.
    The second case comes about when DMA is used asynchronously. This happens, for example, with data acquisition devices that go on pushing data even if nobody is reading them. In this case, the driver should maintain a buffer so that a subsequent read call will return all the accumulated data to user space. The steps involved in this kind of transfer are slightly different:
  4. The hardware raises an interrupt to announce that new data has arrived.
  5. The interrupt handler allocates a buffer and tells the hardware where to transfer its data.
  6. The peripheral device writes the data to the buffer and raises another interrupt when it’s done.
  7. The handler dispatches the new data, wakes any relevant process, and takes care of housekeeping.

A variant of the asynchronous approach is often seen with network cards. These cards often expect to see a circular buffer (often called a DMA ring buffer) estab- lished in memory shared with the processor; each incoming packet is placed in the next available buffer in the ring, and an interrupt is signaled. The driver then passes the network packets to the rest of the kernel and places a new DMA buffer in the ring.

Drivers that use the following functions should include <linux/dma-mapping.h>.
By default, the kernel assumes that your device can perform DMA to any 32-bit address. If this is not the case, you should inform the kernel of that fact with a call to:
int dma_set_mask(struct device *dev, u64 mask);

static int alloc_rx_buffers(struct xxx *x)
{
	struct queue *queue = x->queues[0];
	int size;

	size = rx_ring_size * x->rx_buffer_size;
	queue->rx_buffers = dma_alloc_coherent(&x->pdev->dev, size,
					    &queue->rx_buffers_dma, GFP_KERNEL);
}

queue->rx_buffers: 内存的虚拟起始地址,在内核要用此地址来操作所分配的内存。
bp->pdev->dev: struct device指针,可以平台初始化里指定,主要是dma_mask之类,可参考framebuffer。
size: 实际分配大小,传入dma_map_size即可。
queue->rx_buffers_dma: 返回的内存物理地址,dma就可以用。
DMA是设备内置的, dma_mask可以控制该设备可以访问的内存范围。
之后, 假如有数据包到了, 网卡就把它放到上述dma分配的内存里(DMA缓冲区)里, 操作系统可以从该dma缓冲区拿走数据, 提交至协议栈。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值