麻省大学排名:e1000中DMA传输的问题
来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 06:57:25
看看pci_map_single和pci_unmap_single分别是怎么实现的:
---------------------------------------------------------------------------
linux/include/asm-generic/pci-dma-compact.h
static inline dma_addr_t
pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
{
return dma_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction);
}
/linux/include/asm-i386/dma-mapping.h
------------------------------------------------------------
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
flush_write_buffers();
return virt_to_phys(ptr);
}
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
flush_write_buffers();
return virt_to_phys(ptr);
}
static inline void
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
}
dma_map_single返回ptr的物理地址,dma_unmap_single正好相反,执行这个之后,就可以操作DMA缓存区的 数据。
因为外设在访问内存的时候需要的是物理地址,所以driver才需要做用函数pci_map_single将虚地址转成物理地址。这段地址是由CPU和外设共享的。一般情况下CPU只做读操作,写入是由外设完成的。
现在的网卡大多数都是采用主动DMA的方式。也就是当网卡从网线上接收到数据之后,就会自己启动dma将数据从网卡内部的FIFO传送到配置寄存器指定的内存地址。当一个数据包接收完成之后,产生一个中断通知driver进行处理。整个过程不需要cpu进行干涉。当driver接收到中断的时候,数据已经在内存里存放好了。
对linux系统来说,大多数网卡driver为了提高处理效率,都会将skb->data指向这块共享内存中,这样可以减少一次内存拷贝操作。
在e1000_clean_rx_irq函数里在调用 netif_rx 之前直接访问skb->data就可以了...这就是收到的数据包。
如果真的要自己指定地址,修改 alloc_rx_buf 里面的实现代码就好了
---------------------------------------------------------------------------
linux/include/asm-generic/pci-dma-compact.h
static inline dma_addr_t
pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
{
return dma_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction);
}
/linux/include/asm-i386/dma-mapping.h
------------------------------------------------------------
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
flush_write_buffers();
return virt_to_phys(ptr);
}
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
flush_write_buffers();
return virt_to_phys(ptr);
}
static inline void
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
}
dma_map_single返回ptr的物理地址,dma_unmap_single正好相反,执行这个之后,就可以操作DMA缓存区的 数据。
因为外设在访问内存的时候需要的是物理地址,所以driver才需要做用函数pci_map_single将虚地址转成物理地址。这段地址是由CPU和外设共享的。一般情况下CPU只做读操作,写入是由外设完成的。
现在的网卡大多数都是采用主动DMA的方式。也就是当网卡从网线上接收到数据之后,就会自己启动dma将数据从网卡内部的FIFO传送到配置寄存器指定的内存地址。当一个数据包接收完成之后,产生一个中断通知driver进行处理。整个过程不需要cpu进行干涉。当driver接收到中断的时候,数据已经在内存里存放好了。
对linux系统来说,大多数网卡driver为了提高处理效率,都会将skb->data指向这块共享内存中,这样可以减少一次内存拷贝操作。
在e1000_clean_rx_irq函数里在调用 netif_rx 之前直接访问skb->data就可以了...这就是收到的数据包。
如果真的要自己指定地址,修改 alloc_rx_buf 里面的实现代码就好了
e1000中DMA传输的问题
启用DMA传输模式
利用GPRS无线网络传输图片的问题
股市中DMA技术指标的原理和实战应用简介
中威电子:领先的数字视频光纤传输系统提供商
DMA
科学家探讨“时间中传输”
股票软件中,MA、 MACD 、RSI 、DMA、EXPMA等等。代表什么意思。具体的指标...
FTP的传输模式
公共广播系统的传输方式
STM32---DMA(USART)的演示
用卫星传输同洲IP over DVB等接入方式接入可以解决信息高速公路入户的问题
DMA指标的原理和计算方法
DMA指标的原理和计算方法
简单的电脑红外线传输连接器
AGP接口显卡模式的传输原理
纪检监察信息的写作与网上传输
IMT-2000无线传输技术方案的
抽考中存在的问题
AI中常见的问题
60分钟K线DMA指标的参数设置
DMA 3
DMA方式
第六讲:纪检监察信息的写作与网上传输