1 fd 与ion buffer, file绑定
简单总结就是申请一个buffer,再创建一个dmabuf 结构体然后将,然后将dmabuf中得指针指向buffer,dmabuf 再传递给一个匿名的inode,获取到一个file,这样file和dmabuf绑定起来,也就和buffer关联上。然后再从进程中分配一个空闲的fd,将fd 和file囊绑定。这样就能通过fd 快速查找到buffer。file 是个全系统的,他和进程无关,但是fd 是每个进程都是自己独立的,所以再跨进程传输时只需要保证fd 和同一个file绑定就可以实现buffer的共享。
高通camera 申请ion buffer 并且smmu 映射是在cam_mem_mgr_alloc_and_map 函数种。
cam_mem_mgr_alloc_and_map->cam_mem_util_ion_alloc
cam_mem_util_ion_alloc 函数会返回dma-buf 和fd。确定分配得buffer 大小, 从哪个heap种分配,ion有很多heap。会调用
cam_mem_util_get_dma_buf_fd。
cam_mem_mgr_alloc_and_map->cam_mem_util_ion_alloc->cam_mem_util_get_dma_buf_fd
static int cam_mem_util_get_dma_buf_fd(size_t len,
size_t align,
unsigned int heap_id_mask,
unsigned int flags,
struct dma_buf **buf,
int *fd)
{
struct dma_buf *dmabuf = NULL;
int rc = 0;
if (!buf || !fd) {
CAM_ERR(CAM_MEM, "Invalid params, buf=%pK, fd=%pK", buf, fd);
return -EINVAL;
}
// 分配一个buffer 并且将buffer 与dma-buf 结构体绑定
*buf = ion_alloc(len, heap_id_mask, flags);
if (IS_ERR_OR_NULL(*buf))
return -ENOMEM;
/* 从当前进程种分配一个空闲得fd,注意这里是从进程得到fd,fd 关联得file file却不是
*属于进程的,所以不能close 就万事大吉。close 是将fd重新放入进程得空闲数组种,file
*得索引值只是减1.file 如果索引值原本不是1,那么file 不会释放,分配得buffer就不会释放*/
*fd = dma_buf_fd(*buf, O_CLOEXEC);
if (*fd < 0) {
CAM_ERR(CAM_MEM, "get fd fail, *fd=%d", *fd);
rc = -EINVAL;
goto get_fd_fail;
}
//dma_buf_get 是对前面分配得匿名file 索引值加1.因为分配得时候已经加1,
//这里再加1 实际上所以值已经变为2
dmabuf = dma_buf_get(*fd);
if (IS_ERR_OR_NULL(dmabuf)) {
CAM_ERR(CAM_MEM, "dma_buf_get failed, *fd=%d", *fd);
rc = -EINVAL;
}
return rc;
get_fd_fail:
dma_buf_put(*buf);// dma_buf_put 是与dma_buf_get相对得,就是将所以值再减去1
return rc;
}
1.1获得一个ion buffer 和file
ion_

本文深入解析DMA-BUF与IONBUFFER的工作原理,详细介绍了如何通过IONBUFFER和DMA-BUF实现内存缓冲区的管理和跨进程共享。文章涵盖IONBUFFER的分配、与DMA-BUF的绑定过程,以及FD与FILE的关联机制。
最低0.47元/天 解锁文章
1401

被折叠的 条评论
为什么被折叠?



