内核空间到用户空间的共享内存映射

原创 2012年03月28日 22:20:33

当内核空间和用户空间存在大量数据交互时, 共享内存映射就成了这种情况下的不二选择; 它能够最大限度的降低内核空间和用户空间之间的数据拷贝, 从而大大提高系统的性能.


以下是创建从内核空间到用户空间的共享内存映射的模板代码(在内核2.6.18和2.6.32上测试通过):

1.内核空间分配内存:

#include <linux/types.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>

int mmap_alloc(int require_buf_size)
{
  struct page *page;
 
  mmap_size = PAGE_ALIGN(require_buf_size);

#if USE_KMALLOC //for kmalloc
  mmap_buf = kzalloc(mmap_size, GFP_KERNEL);
  if (!mmap_buf) {
    return -1;
  }
  for (page = virt_to_page(mmap_buf ); page < virt_to_page(mmap_buf + mmap_size); page++) {
    SetPageReserved(page);
  }
#else //for vmalloc
  mmap_buf  = vmalloc(mmap_size);
  if (!mmap_buf ) {
    return -1;
  }
  for (i = 0; i < mmap_size; i += PAGE_SIZE) {
    SetPageReserved(vmalloc_to_page((void *)(((unsigned long)mmap_buf) + i)));
  }
#endif

  return 0;
}

2.用户空间映射内存

int test_mmap()
{
  mmap_fd = open("/dev/mmap_dev", O_RDWR);
  mmap_ptr = mmap(NULL, mmap_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, mmap_fd, 0);
  if (mmap_ptr == MAP_FAILED) {
    return -1;
  }
  return 0;
}


3.内核空间映射内存: 实现file_operations的mmap函数
static int mmap_mmap(struct file *filp, struct vm_area_struct *vma)
{
  int ret;
  unsigned long pfn;
  unsigned long start = vma->vm_start;
  unsigned long size = PAGE_ALIGN(vma->vm_end - vma->vm_start);

  if (size > mmap_size || !mmap_buf) {
    return -EINVAL;
  }

#if USE_KMALLOC
  return remap_pfn_range(vma, start, (virt_to_phys(mmap_buf) >> PAGE_SHIFT), size, PAGE_SHARED);
#else
  /* loop over all pages, map it page individually */
  while (size > 0) {
          pfn = vmalloc_to_pfn(mmap_buf);
          if ((ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED)) < 0) {
            return ret;
          }
          start += PAGE_SIZE;
          mmap_buf += PAGE_SIZE;
          size -= PAGE_SIZE;
  }
#endif
  return 0;
}

static const struct file_operations mmap_fops = {
  .owner = THIS_MODULE,
  .ioctl = mmap_ioctl,
  .open = mmap_open,
  .mmap = mmap_mmap,
  .release = mmap_release,
};

4.用户空间撤销内存映射

void test_munmap()
{    
  munmap(mmap_ptr, mmap_size);
  close(mmap_fd);
}


5.内核空间释放内存; 必须在用户空间执行munmap系统调用后才能释放

void mmap_free()
{
#if USE_KMALLOC
  struct page *page;
  for (page = virt_to_page(mmap_buf); page < virt_to_page(mmap_buf + mmap_size); page++) {
    ClearPageReserved(page);
  }
  kfree(mmap_buf);
#else
  int i;
  for (i = 0; i < mmap_size; i += PAGE_SIZE) {
    ClearPageReserved(vmalloc_to_page((void *)(((unsigned long)mmap_buf) + i)));
  }
  vfree(mmap_buf);
#endif
  mmap_buf = NULL;
}


参考资料:

http://www.scs.ch/~frey/linux/memorymap.html



Linux内核空间映射到用户空间

当内核空间和用户空间存在大量数据交互时, 共享内存映射就成了这种情况下的不二选择; 它能够最大限度的降低内核空间和用户空间之间的数据拷贝, 从而大大提高系统的性能.   以下是创建从内核空间到用户...
  • wavemcu
  • wavemcu
  • 2012年12月26日 21:44
  • 3409

Linux用户空间与内核空间内存映射

inux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数据...
  • Fybon
  • Fybon
  • 2014年01月09日 16:30
  • 2854

利用mmap实现用户空间与内核空间的共享内存通信

利用mmap实现用户空间与内核空间的共享内存通信 秦白衣 Arethe Qin arethe.kernel@gmail.com            用户空间与内核空间的通信方法有很多,如i...
  • arethe
  • arethe
  • 2011年11月06日 18:15
  • 8452

Linux内核空间到用户空间的共享内存映射

当内核空间和用户空间存在大量数据交互时, 共享内存映射就成了这种情况下的不二选择; 它能够最大限度的降低内核空间和用户空间之间的数据拷贝, 从而大大提高系统的性能.   以下是创建从内核空间到用户...

C++ 处理 Kill 信号、Ctrl+C信号

来自: http://blog.csdn.net/xian0617/article/details/6689357/* * WaitQuitSignal.h * *  Created on: Au...
  • yaxf999
  • yaxf999
  • 2012年04月06日 10:38
  • 6029

munmap导致的BUG

一次线上BUG的分析过程

Linux用户空间与内核空间内存映射

Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数...

linux内核空间的内存映射

linux内核空间的内存映射       逻辑地址(Logical Address) (即虚拟地址)是指由程式产生的和段相关的偏移地址部分。例如,你在进行C语言指针编程中,能读取指针变量本身值(...

linux 内存映射 remap_pfn_range操作(内核地址映射到用户空间)

1. mmap.c: #include #include #include #include #include #include #include #include #include ...

内核和用户空间共享内存的实现例程-proc和mmap(zt)

内核和用户空间共享内存的实现例程-proc和mmap(zt) 2008-11-13 15:08 之所以想写这篇帖子,是有两个方面原因。其一是内核版有一个关于《内核可以从线性 地址直接计算物...
  • gmzd84
  • gmzd84
  • 2011年12月14日 22:11
  • 188
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内核空间到用户空间的共享内存映射
举报原因:
原因补充:

(最多只允许输入30个字)