(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()函数是为了达到一致性内存的目的,它分配指定大小的一致性内存,其物理起始地址存放在dma_handle中,函数返回值为这段内存的虚拟起始地址。 dma_alloc_coherent()函数返回的虚拟地址尽量是非缓存的,这样设备向这块地址放数据包,OS响应中断后可以从这块地址拿包。
在调用此函数后,应立即检查返回值是否为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; } ...
不幸的是,分配失败了,我无法解释系统日志的原因。我可能是在用结构设备做错事。dma_alloc_coherent中的设备引用是用来干什么的? 这是我目前的尝试。这是一个修改过的虚拟字符设备(请注意,我现在知道它是完全垃圾的,根本不应该做dma): 代码语言:javascript ...
1、函数的返回值是一个 void *。代表缓冲区的内核虚拟地址 2、相关的总线地址(物理地址),保存在dma_handle中 2、调用 A =dma_alloc_coherent(B,C,D,GFP_KERNEL); 含义: A: 内存的虚拟起始地址,在内核要用此地址来操作所分配的内存 B: struct device指针。能够平台初始化里指定。主要是dma_mask之类。可參...
// 返回值为内核虚拟地址。 return (void *)c->vm_start 1. I/O 端口和 I/O 内存 每个外设都是通过读写它的寄存器来控制. 大部分时间一个设备有几个寄存器, 并且在连续地址存取它们, 或者在内存地址空间或者在 I/O 地址空间. 在硬件级别上, 内存区和 I/O 区域没有概念上的区别: 它们都是通过在地址...
通过dma_alloc_coherent接口可以申请连续的大块内存。该函数处理了缓冲区的分配和映射。前两个参数是device结构和所需缓冲区的大小。函数的返回值是缓冲区的内核虚拟地址,可以被驱动程序使用。相关的总线地址则保存在dma_handle中。 如果设备需要的DMA区域比单个页还小,就要使用DMA池。DMA池是一个生成小型、一致性DMA...
SetPageReserved(page); set_pte_at(&init_mm, vaddr, pte, mk_pte(page, pgprot_noncached(PAGE_KERNEL))); page++; pte++; vaddr += PAGE_SIZE; } while (size -= PAGE_SIZE); // 返回值为内核虚拟地址。 return (void *)c->vm_start...