- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
目前,我正在使用 example driver从中学习,并从中建立了自己的自定义驱动程序。 mmap 代码几乎完全相同,除了我允许用户管理他们自己请求的大小并以此为基础进行内存分配,以及我在/dev 中自动创建字符设备这一事实。
为了解释上下文,对于我的用例,我想缩小我遇到的问题的范围。 dma_mmap_coherent
在使用 kmalloc 内存时可测试地工作,但是当我有一个保留的物理地址区域时,我想使用 remap_pfn_range 似乎安静地工作,并且 dmesg 不报告任何错误,但是当我去阅读,无论我在那里写了什么,它总是返回 0xff 字节。无论我是在 ioremap 内存之后在内核态中使用 iowrite 和 ioread,还是尝试使用小型 mmap 用户态测试在用户态中写入,都是如此。
我已经尽我所能对这个主题进行了尽可能多的研究。我能找到的关于 remap_pfn_range 的文档是 kernel.org page , 以及 remap_pfn_range 上的一些内核 gmain 邮件列表存档替换了 remap_page_range。至于 dma_mmap_coherent,我能找到更多一点,including a presentation from the linux archives .
最终还是要有区别的;似乎有很多不同的方法可以将内核内存映射到用户空间。我的具体问题是:dma_mmap_coherent
和 remap_pfn_range
之间有什么区别?
编辑 提供将内核内存映射到用户空间的方法的一般概述可能会很好,涵盖如何在内核驱动程序 mmap 回调中使用不同的 api。
最佳答案
dma_mmap_coherent() 在 dma-mapping.h 中定义作为 dma_mmap_attrs() 的包装器。 dma_mmap_attrs() 尝试查看是否有一组 dma_mmap_ops与您正在操作的设备 (struct device *dev) 相关联,如果不是它调用 dma_common_mmap() 最终导致调用 remap_pfn_range(),在将页面保护设置为不可缓存后(参见 dma- 中的 dma_common_mmap())映射.c).
关于将内核内存映射到用户空间的工作原理的一般概述,以下是我从用户空间映射 DMA 缓冲区的快速简单方法:
通过 IOCTL 分配一个缓冲区,并为每个带有一些标志的缓冲区指定一个缓冲区 ID:
/* A copy-from-user call needs to be done before in the IOCTL */
static int my_ioctl_alloc(struct my_struct *info, struct alloc_info *alloc)
{
...
info->buf->kvaddr = dma_alloc_coherent(dev, alloc->size, info->buf->phyaddr, GFP_KERNEL);
info->buf->buf_id = alloc->buf_id;
...
}
定义一个 mmap 文件操作:
static const struct file_operations my_fops = {
.open = my_open,
.close = my_close,
.mmap = my_mmap,
.unlocked_ioctl = my_ioctl,
};
不要忘记在驱动程序的探测函数中的某处注册 my_fops 结构。
实现 mmap 文件操作:
static int my_mmap(struct file *fptr, struct vm_area_struct *vma)
{
...
desc_id = vma->vm_pgoff;
buf = find_buf_by_id(alloc, desc_id);
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
ret = remap_pfn_range(vma, vma->vm_start, buf->phyaddr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot);
if (ret) {
/* Error Handle */
}
return 0;
}
有了这个,你的内核驱动程序应该有最少的分配和 mmap 缓冲区。释放缓冲区是获得奖励积分的练习!
在应用程序中,您将打开()文件并获取有效的文件描述符 fd,调用分配 IOCTL 并在执行复制到内核之前设置缓冲区 ID。在 mmap 中,您将通过偏移参数提供缓冲区 ID:
mmap(NULL, buf_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buffer_id << PAGE_SHIFT);
PAGE_SHIFT 是内核中固定的依赖于体系结构的编译时宏。希望这可以帮助。
这不是 checkpatch.pl 兼容代码,也不是最佳实践,但这是我知道如何执行此操作的一种方法。欢迎提出意见/改进/建议!
请参阅 Linux 设备驱动程序 - 第 15 章:内存映射和 DMA,以获取教科书示例以及为感兴趣的读者提供的良好背景信息。
关于c - dma_mmap_coherent 和 remap_pfn_range 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34516847/
平时很少在jquery中用到this。查看代码时发现用到了,就调试出this的值,心想原来如此。还是挺有用的。这里总结一下this与$(this)的区别和使用。 $(this)生成的是什么?
使用单例类和应用程序范围的托管 bean 来保存应用程序数据有区别吗? 我需要查找某些 JNDI 资源,例如远程 bean 接口(interface),因此我为自己编写了一个单例来缓存我的引用并且只允
如果您仔细查看包含的图片,您会注意到您可以使用 Eclipse IDE 重构 Groovy 代码并将方法转换为闭包,反之亦然。那么,闭包到底是什么,它与方法有什么不同呢?有人可以举一个使用闭包的好例子
vagrant box repackage有什么区别( docs ) 和 vagrant package ( docs )? 我意识到 vagrant package仅适用于 VirtualBox 提
我想看看是否有人可以解释为什么以下代码适用于 valueOf 但不适用于其他代码。 import java.math.BigDecimal; public class Change { publ
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicates: What is Closures/Lambda in PHP or Javascript in layman te
This question already has answers here: Vagrant, Docker, Puppet, Chef (3个答案) 2年前关闭。 docker和chef有什么共同
以下代码在95%的机器上产生相同的输出,但是在几台机器上却有所不同。在 Debug模式下,输出: Changing from New to Fin OK 但在 Release模式下: Changing
////Creating Object var Obj; // init Object Obj= {}; 它们之间有什么区别两个? 有没有可能把它变成一个单行? 这样使用有什么好处吗?
我想找出定时器服务之间的区别。我应该使用哪个以及何时使用。我正在使用 Jboss 应用服务器。 1) java.ejb.Schedule。 @Schedule注解或配置自xml。 2) javax.e
我发现在 C++ 中可以通过三种不同的方式将对象传递给函数。假设我的类(class)是这样的: class Test { int i; public: Test(int x);
有什么区别。 public class Test { public static void main(String args[]) { String toBeCast = "c
如果我有一列,设置为主索引,设置为INT。 如果我不将其设置为自动递增,而只是将唯一的随机整数插入其中,与自动递增相比,这是否会减慢 future 的查询速度? 如果我在主索引和唯一索引为 INT 的
这两种日期格式有什么区别。第一个给出实际时间,第二个给出时间购买添加时区偏移值。 NSDateFormatter * dateFormatter = [[NSDateFormatter alloc]
如果有一个函数,请说foo: function foo() { console.log('bar'); } 那么在 JavaScript 中,从另一个函数调用一个函数有什么区别,如下所示: f
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
代码是什么: class Time { private: int hours; int minutes; int seconds; pu
我知道这是非常基本的,但有人介意解释一下这两个数组声明之间的区别吗: #include array myints; ...和: int myints[5]; ...以及为什么 myints.size
我学会了如何根据 http://reference.sitepoint.com/css/specificity 计算 css 特异性但是,基于this reference,我不明白伪类(来自c)和伪元
为什么在运行 2) 时会出现额外的空行?对我来说 1 就像 2。那么为什么 2) 中的额外行? 1) export p1=$(cd $(dirname $0) && pwd) #
我是一名优秀的程序员,十分优秀!