嵌入式linux之DMA驱动

2019-07-12 20:26发布

http://blog.csdn.net/jingzhesiye/article/details/8610865

malloc分配的内存在虚拟地址上是连续的.

1、linux内核管理内存空间的分配,所有程序对内存空间的申请和其他操作,最终都会交给内核来管理。

2、linux实现的是“虚拟内存系统”,对用户而言,所有内存都是虚拟的,也就是说程序并不是直接运行在物理内存上,而是运行在虚拟内存上,然后由虚拟内存转换到物理内存。

3、linux将所有的内存都以页为单位进行划分,通常每一页是4KB;

4、在对虚拟内存地址到物理内存地址进行转换时,内核会对地址的正确性进行检查,如果地址是合法的,内核就会提供对应的物理内存分页;如果是申请内存空间,内核就会检查空余的物理内存分页,并加以分配,如果物理内存空间不足,内核会拒绝此次申请;

5、使用malloc分配的内存空间在虚拟地址空间上是连续的,但是转换到物理内存空间上有可能是不连续的,因为有可能相邻的两个字节是在不同的物理分页上;

1、页对齐内存大小:dma_map_size = PAGE_ALIGN(MY_DATA_SIZE + PAGE_SIZE); MY_DATA_SIZE是你想分配的大小. 2、调用 A = dma_alloc_writecombine(B,C,D,GFP_KERNEL); 含义: A: 内存的虚拟起始地址的页偏移,在内核要用此地址来操作所分配的内存 B: struct device指针,可以平台初始化里指定,主要是dma_mask之类,可参考framebuffer C: 实际分配大小,传入dma_map_size即可 D: 返回的内存物理地址,dma就可以用。 所以,A和D是一一对应的,只不过,A是虚拟地址,而D是物理地址。对任意一个操作都将改变缓冲区内容。当然要注意操作环境。 参见S3C2410 LCD驱动中的函数s3c2410fb_map_video_memory(): unsigned map_size = PAGE_ALIGN(info->fix.smem_len); info->screen_base = dma_alloc_writecombine(fbi->dev, map_size,&map_dma, GFP_KERNEL); DMA传输过程中的传输总长度”
1.DSZ:读写数据的size,1,2,4byte
2.TSZ:单次传输(一次),突发传输(4次)
3.TC:传输次数 总长度 = TC*TSZ(1/4)*DSZ