linux 之dma_buf (1)- dma_buf 的初步介绍

一、前言

因为不管是 Video、Camera 还是 Display、GPU,它们的buffer都来自于ION,而 ION 正是基于 dma-buf 实现的。

二、概念

dma-buf 的出现就是为了解决各个驱动之间 buffer 共享的问题,因此它本质上是 buffer 与 file 的结合,即 dma-buf 既是块物理 buffer,又是个 linux file。buffer 是内容,file 是媒介,只有通过 file 这个媒介才能实现同一 buffer 在不同驱动之间的流转。

一个典型的 dma-buf 应用框图如下:

通常,我们将分配 buffer 的模块称为 exporter,将使用该 buffer 的模块称为 importer 或 user。但在本系列文章中,importer 特指内核空间的使用者,user 特指用户空间的使用者。

有的人习惯将 exporter 说成是生产者,importer 说成是消费者,我个人认为这样的说法并不严谨。举例来说,Android 系统中,graphic buffer 都是由 ION 来分配的,GPU 负责填充该 buffer,DPU 负责显示该 buffer。那么在这里,ION 则是 exporter,GPU 和 DPU 则都是 importer。但是从生产者/消费者模型来讲,GPU 则是生产者,DPU 是消费者,因此不能片面的认为 exporter 就是生产者。

三、最简单的 dma-buf 驱动程序

 如下代码演示了如何编写一个最简单的 dma-buf 驱动程序,我将其称为 dummy 驱动,因为它什么事情也不做。

export_test.c

#include <linux/dma-buf.h>
#include <linux/module.h>

static struct sg_table *exporter_map_dma_buf(struct dma_buf_attachment *attachment,
					 enum dma_data_direction dir)
{
	return NULL;
}

static void exporter_unmap_dma_buf(struct dma_buf_attachment *attachment,
			       struct sg_table *table,
			       enum dma_data_direction dir)
{
}

static void exporter_release(struct dma_buf *dmabuf)
{
}

/*static void *exporter_kmap_atomic(struct dma_buf *dmabuf, unsigned long page_num)
{
	return NULL;
}

static void *exporter_kmap(struct dma_buf *dmabuf, unsigned long page_num)
{
	return NULL;
}*/

static int exporter_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
{
	return -ENODEV;
}

static const struct dma_buf_ops exp_dmabuf_ops = {
	.map_dma_buf = exporter_map_dma_buf,
	.unmap_dma_buf = exporter_unmap_dma_buf,
	.release = exporter_release,
	//.map_atomic = exporter_kmap_atomic,
	//.map = exporter_kmap,
	.mmap = exporter_mmap,
};

static int __init exporter_init(void)
{
	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
	struct dma_buf *dmabuf;

	exp_info.ops = &exp_dmabuf_ops;
	exp_info.size = PAGE_SIZE;
	exp_info.flags = O_CLOEXEC;
	exp_info.priv = "null";

	dmabuf = dma_buf_export(&exp_info);

	return 0;
}

module_init(exporter_init);

从上面的代码来看,要实现一个 dma-buf exporter驱动,需要执行3个步骤:

  1. dma_buf_ops
  2. DEFINE_DMA_BUF_EXPORT_INFO
  3. dma_buf_export()

注意: 其中 dma_buf_ops 的回调接口中,如下接口又是必须要实现的,缺少任何一个都将导致 dma_buf_export() 函数调用失败!

  • map_dma_buf
  • unmap_dma_buf
  • map
  • map_atomic
  • mmap
  • release

从 linux-4.19 开始,map_atomic 接口被废弃,map 和 mmap 接口不再被强制要求。

源码中,已经去掉 map 和map_atomic

 编译加载后:

 在实际运行的过程中,细心的小伙伴可能会发现,该 exporter_dummy.ko 只能被 insmod,无法被 rmmod。关于该问题的原因,将在后面文章解释。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值