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