Chinaunix首页 | 论坛 | 博客
  • 博客访问: 368385
  • 博文数量: 82
  • 博客积分: 1104
  • 博客等级: 少尉
  • 技术积分: 926
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-16 15:14
文章分类
文章存档

2012年(82)

分类: LINUX

2012-07-03 15:37:11

在camera V4L2中,系统使用了alloc_page( )申请了一段内存给DMA使用,产生疑问:dma的内存不是在申请的时候加上flags:__GFP_GMA,此下文给出答复,同时结合在DQBUF中dma_cache_maint( )(有转博文)保证了dma和cache一致性。


本文针对ARM体系结构,参考的内核版本是2.6.32。

1.       为什么存在DMA ZONE?

原因是某些硬件的DMA引擎不能访问到所有的内存区域,因此,加上一个DMA ZONE,当使用GFP_DMA方式申请内存时,获得的内存限制在DMA_ZONE的范围内,这些特定的硬件需要使用GFP_DMA方式获得可以做DMA的内存;

如果系统中所有的设备都可选址所有的内存,那么DMA ZONE覆盖所有内存。

2.       device结构体的dma_mask和dma_coherent_mask的作用分别是什么?

dma_mask是设备DMA能访问的内存范围,dma_coherent_mask则作用于申请一致性DMA缓冲区。

3.       dma_alloc_coherent分配的内存一定在DMA ZONE内吗?

答案是否定的,应该说绝对多数情况下都不在DMA ZONE内。dma_alloc_coherent会调用__dma_alloc,__dma_alloc判断是否从DMA ZONE申请内存的依据是:

        u64 mask = get_coherent_dma_mask(dev);

        …

        if (mask < 0xffffffffULL)

                gfp |= GFP_DMA;

 

        page = alloc_pages(gfp, order);

        if (!page)

                goto no_page;

由此可见,只有当设备的dma_coherent_mask小于全部地址访问 (0xFFFFFFFF)的时候,也就是针对少数特殊设备,才会去DMA ZONE申请内存,其他时候直接从NORMAL ZONE获得内存。而对于绝大多数设备而言,DMA寻址范围是0xFFFFFFFF。

4.       什么时候需要DMA bounce?

最常见的case是,当底层驱动做DMA操作时所使用的内存不是透过 dma_alloc_coherent等一致性DMA缓冲区API获得,而是来自于驱动的上层,譬如文件系统,那么驱动在执行DMA操作时,会调用流式 DMA API,如map_single等。而如果上层传下来的内存超过了设备DMA可寻址的内存范围,即:

needs_bounce = (dma_addr | (dma_addr + size - 1)) & ~mask;

得到满足的时候,这片区域不能执行DMA,map_single底层会自动执行DMA。

阅读(3832) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~