Articles of mmap

Linux设备驱动程序允许FPGA直接DMA到CPU RAM

我正在写一个linux设备驱动程序,允许一个FPGA(通过PCI express连接到PC)直接将数据直接写入CPU RAM中。 这需要在没有任何交互的情况下发生,并且用户空间需要访问数据。 一些细节: – 运行64位的Fedora 14 – 系统有8GB的RAM – FPGA(Cyclone IV)位于PCIe卡上 为了实现这一点,我执行了以下操作: – 在memub中保留了2GB的RAM,使用memmap 6GB $ 2GB(无法启动,我添加了mem = 2GB)。 我可以看到/ proc / meminfo中保留了高2GB的RAM – 映射BAR0允许读写FPGA寄存器(这个工作完美) – 在我的驱动程序中使用remap_pfn_range()实现了mmap函数 – 使用ioremap获取缓冲区的虚拟地址 – 添加ioctl调用(用于testing)将数据写入缓冲区 – 通过进行ioctl调用将数据写入缓冲区并validation数据在用户空间的缓冲区中来testingmmap 我面临的问题是当FPGA开始DMA数据到我提供的缓冲区地址。 我不断得到PTE错误(从DMAR :)或与下面的代码我得到以下错误:DMAR:[DMA写入]请求设备[01:00.0]故障地址186dc5000 DMAR:[故障原因01]根目录中的当前位清零DRHD:处理故障状态寄存器3 根据FPGA的DMA,第一行的地址每次增加0x1000 这是我的init()代码: #define IMG_BUF_OFFSET 0x180000000UL // Location in RAM (6GB) #define IMG_BUF_SIZE 0x80000000UL // Size of […]

为什么mmap()失败,文件复制程序的目标文件的权限被拒绝?

我想尝试通过使用mmap()在Linux中使用内存映射I / O将文件的内容复制到另一个文件。 目的是自己检查一下,如果这比使用fread()和fwrite()更好,它将如何处理大文件(例如,像GiBs几个,因为文件被读取整个我想知道,如果我需要有这样的内存量)。 这是我现在正在使用的代码: // Open original file descriptor: int orig_fd = open(argv[1], O_RDONLY); // Check if it was really opened: if (orig_fd == -1) { fprintf(stderr, "ERROR: File %s couldn't be opened:\n", argv[1]); fprintf(stderr, "%d – %s\n", errno, strerror(errno)); exit(EX_NOINPUT); } // Idem for the destination file: int dest_fd = open(argv[2], O_WRONLY | […]

错误:无法mmap文件:vmlinux

在新安装的虚拟机中,编译x86体系结构的内核时出现此错误: $ Could not mmap file: vmlinux $ make: *** [vmlinux] Error 1 这是我第一次看到它。 我已经把/proc/sys/kernel/shmmax的大小增加到了128MB,但是并没有解决这个问题。 有任何想法吗? 谢谢! 🙂

如何实现或模拟MADV_ZERO?

我希望能够在不调用任何io的情况下将文件内存映射的范围清零(为了高效地顺序覆盖大文件而不引起任何磁盘读取io)。 做std::memset(ptr, 0, length)会导致从磁盘读取页面,如果它们还不在内存中,即使整个页面被覆盖,从而完全破坏磁盘性能。 我希望能够做一些像madvise(ptr, length, MADV_ZERO)这样的madvise(ptr, length, MADV_ZERO) ,它会将范围调整为零(类似于FALLOC_FL_ZERO_RANGE ),以便在访问指定范围时导致零填充页错误,而不是常规的io页错误。 不幸的是, MADV_ZERO不存在。 尽pipeFALLOC_FL_ZERO_RANGE中存在相应的标志FALLOC_FL_ZERO_RANGE ,并且可以与fwrite一起使用,以达到类似的效果,尽pipe没有即时的跨进程一致性。 我猜想一个可能的select是使用MADV_REMOVE 。 然而,从我的理解可以导致文件碎片,并阻止其他操作,同时完成这使我不确定其长期的性能影响。 我对Windows的经验是,类似的FSCTL_SET_ZERO_DATA命令在调用时可能会导致显着的性能高峰。 我的问题是如何实现或模拟MADV_ZERO共享映射,最好在用户模式? 1. /dev/zero/ 我已经读过它被build议 只读/dev/zero到选定的范围 。 虽然我不太清楚“朗读范围”是什么意思,怎么做。 它是从/dev/zero到内存范围fread ? 不知道如何避免访问常规页面错误? 对于Linux,只需将/dev/zero读入选定范围。 内核已经优化了这种情况下的匿名映射。 如果这样做一般来说太难实施了,我 build议MADV_ZERO应该有这样的效果:完全像阅读 / dev / zero进入范围,但始终有效。 编辑:继续线程有点进一步 ,事实certificate,它实际上不会工作。 当你处理共享映射时,它不会做技巧。 2. MADV_REMOVE 在Linux中实现它的一个猜测(即不在用户应用程序中,我更喜欢)可以通过简单地复制和修改MADV_REMOVE ,即madvise_remove使用FALLOC_FL_ZERO_RANGE而不是FALLOC_FL_PUNCH_HOLE 。 虽然我在猜测这个问题上有点头痛,特别是因为我不太明白vfs_allocate的代码在做什么: // madvice.c static long madvise_remove(…) … /* * Filesystem's […]

mmap / mprotect-readonly零页是否会计入已提交的内存?

我想在我的进程中保留以前使用但目前不需要的内存的虚拟地址空间。 我感兴趣的是主机内核是Linux的情况,它被configuration为防止overcommit(它通过详细logging所有提交的内存)。 如果我只想阻止我的应用程序不再占用物理内存或交换到磁盘(浪费资源)的数据,那么我可以使内核不需要它,或者在它之上新build零页。 但是,这些方法都不一定会减less提交的内存数量,其他进程则不能使用。 如果我用标记为只读的全新零页来replace页面怎么办? 我的意图是,他们不计入承诺的内存,并进一步,我可以稍后使用mprotect使它们可写,并且它将失败,如果使它们可写将超过承诺的内存限制。 我的理解是正确的吗? 这会工作吗?

如何使用/ dev / kmem?

更新了我的post… 我得到了程序。 它在/dev/kmem和/dev/mem 。 我想我可以从代码中学到一些东西。 但是当我在Beagle Board上运行的时候,结果如下: case 1: ( if(1) ) root@omap:/home/ubuntu/tom# ./kmem_mem /boot/System.map-3.0.4-x3 found jiffies at (0xc0870080) c0870080 /dev/kmem read buf = 319317 jiffies=319317 (read from virtual memory) /dev/mem: the offset is 870080 the page size = 4096 mmap: Invalid argument case 2: ( if(0) ) root@omap:/home/ubuntu/tom# ./kmem_mem /boot/System.map-3.0.4-x3 found jiffies at (0xc0870080) […]

在共享内存结果进程之间进行通信零拷贝?

我正在编写一个networking守护进程,在内核2.6的Linux上,它有一个生产者进程和N个消费者进程 ,它们不会对数据做任何改变,也不会对生产者产生任何回应。 只要生产者进程产生一个数据对象,其长度从几个10字节到几十K字节不等,就必须把数据对象传递给一个可用的消费者进程。 第一次,我考虑使用一个命名/无名PIPE。 但是,它们会成为内存复制开销。 生产者的用户空间缓冲区–copy – >内核空间PIPE缓冲区 内核空间PIPE缓冲区–copy – >用户的用户空间缓冲区 由于该程序可能与低延迟的大量对等设备一起工作,所以复制开销可能是有害的。 因此,我决定用mmap()来使用POSIX共享内存。 我只是想知道,如果与使用mmap()的POSIX共享内存进程之间共享数据不会导致任何内存复制 ,不像PIPE。 另外,有没有其他的方式来分享进程之间的数据,但结果零拷贝? 该程序将在Linux上运行,并具有最新版本的内核,可能不必具有跨平台function。 我决定不为每个消费者/产品产生/运行一个线程,而是由于devise问题而产生一个过程。 感谢您的回复。

如何为mmapselect一个固定的地址?

mmap()可以select提供一个固定的位置来放置地图。 我想mmap一个文件,然后在每个程序的同一个虚拟地址上提供给几个不同的程序。 我不在乎地址是什么,只要他们都使用相同的地址。 如果需要的话,地址可以在运行时由其中一个人select(并通过其他方式与其他人沟通)。 Linux保证未被使用的内存区域(由应用程序和内核)可以映射到哪里? 我怎样才能find一个在几个正在运行的应用程序中可用的地址?

mmap:在用户空间映射一个由kmalloc分配的内核缓冲区

哪一个是正确的方式来映射在用户空间处理缓冲区分配kmalloc? 也许我不明白内存映射尚未…我写了一个内核模块,分配此缓冲区(例如120字节),我会读取和写入用户空间的过程中。 很明显,我创build了一个char设备,并在file_operations结构中实现了一个mmap方法。 我的方法是: static int my_mmap(struct file *filp, struct vm_area_struct *vma) { //printk(KERN_INFO "Allocated virtual memory length = %d", vma->vm_end – vma->vm_start); long unsigned int size = vma->vm_end – vma->vm_start; if (remap_pfn_range(vma, vma->vm_start, __pa(mem_area) >> PAGE_SHIFT, //what about vma->vm_pgoff? size, vma->vm_page_prot) < 0) return -EAGAIN; vma->vm_flags |= VM_LOCKED; vma->vm_ops = &vmops; vma->vm_flags |= VM_RESERVED; […]

为什么使用shm_open?

做什么的好处: shm_open跟着一个mmap ? 为什么不创build一个常规文件,然后将该fd传递给mmap ? 我看不到shm_open的优势 – 这些只是引用,不是吗? 我读过全家的男人 在我看来,这个“秘密”是在压缩行动 – “types”文件似乎是没有意义的。 任何指针都会很好,特别是在性能帐户。 我的上下文是一个(循环可写)缓冲区(比如说128MB),它将被不断地写入一个进程,并不断被另一个进程抛弃。 举个例子: 这个 open / mmap方法有什么问题。 编辑 准确地说,下面的其中一个比另一个更好: fd = open("/dev/shm/myshm.file", O_CREAT|O_RDWR, S_IRUSR | S_IWUSR); mem = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 与 fd = shm_open("/myshm.file", O_RDWR|O_CREATE, S_IRUSR | S_IWUSR); mem = mmap(…same as before…); 当我在/dev/shm fs下创build一个定期open的文件,并向其中倾倒了一个垃圾文件时,我的可用内存降低了1G,而我的可用磁盘空间保持不变。 这两种方法有什么区别?