(2) 将虚拟地址ret转换成总线地址 这个函数是一个平台相关的函数,以上是在x86平台的实现细节,从这里我们可以看到该函数返回值为linux 内核线性地址,所以对于驱动开发过程的mmap函数实现提供了便利。 但是在powerpc平台却不是这样,笔者就曾经遇到在将pci驱动从x86平台移植到powerpc平台时出现问题。 首先我们来先看一下...
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,intflag); 该函数实际获得两个地址。 1、函数的返回值是一个 void *。代表缓冲区的内核虚拟地址 2、相关的总线地址(物理地址),保存在dma_handle中 2、调用 A =dma_alloc_coherent(B,C,D,GFP_KERNEL); 含义:A: 内...
通过dma_alloc_coherent接口可以申请连续的大块内存。该函数处理了缓冲区的分配和映射。前两个参数是device结构和所需缓冲区的大小。函数的返回值是缓冲区的内核虚拟地址,可以被驱动程序使用。相关的总线地址则保存在dma_handle中。 如果设备需要的DMA区域比单个页还小,就要使用DMA池。DMA池是一个生成小型、一致性DMA...
在调用此函数后,应立即检查返回值是否为NULL。 c void *dma_mem = dma_alloc_coherent(dev, size, &dma_handle, GFP_KERNEL); if (!dma_mem) { // 处理分配失败的情况 printk(KERN_ERR "DMA memory allocation failed "); // 可以进行错误恢复或退出操作 return -ENOMEM; } ...
一个典型的内核配置菜单如下: menu "Network device support" config NETDEVICES bool "Enable Net Devices" depends on NET default y help This is help desciption。 ... endmenu 包含在menu/endmenu中的
// 返回值为内核虚拟地址。 return (void *)c->vm_start 1. I/O 端口和 I/O 内存 每个外设都是通过读写它的寄存器来控制. 大部分时间一个设备有几个寄存器, 并且在连续地址存取它们, 或者在内存地址空间或者在 I/O 地址空间. 在硬件级别上, 内存区和 I/O 区域没有概念上的区别: 它们都是通过在地址...
// 返回值为内核虚拟地址。 return (void *)c->vm_start 1. I/O 端口和 I/O 内存 每个外设都是通过读写它的寄存器来控制. 大部分时间一个设备有几个寄存器, 并且在连续地址存取它们, 或者在内存地址空间或者在 I/O 地址空间. 在硬件级别上, 内存区和 I/O 区域没有概念上的区别: 它们都是通过在地址...
dma_alloc_coherent()函数是为了达到一致性内存的目的,它分配指定大小的一致性内存,其物理起始地址存放在dma_handle中,函数返回值为这段内存的虚拟起始地址。 dma_alloc_coherent()函数返回的虚拟地址尽量是非缓存的,这样设备向这块地址放数据包,OS响应中断后可以从这块地址拿包。
这个函数是一个平台相关的函数,以上是在x86平台的实现细节,从这里我们可以看到该函数返回值为linux 内核线性地址,所以对于驱动开发过程的mmap函数实现提供了便利。 但是在powerpc平台却不是这样,笔者就曾经遇到在将pci驱动从x86平台移植到powerpc平台时出现问题。 首先我们来先看一下两个平台对于dma内存的处理。