码迷,mamicode.com
首页 > 其他好文 > 详细

内核与用户态程序共享内存的方法

时间:2015-03-17 20:18:43      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:

一、首先获取一块物理上连续的物理内存

有多种方法。

(a)通过kernel命令行参数预留一些内存

这种方法,适合于需要大块的物理连续的内存。

假设物理内存总量为256M。命令行参数中,指定 mem=224M。即只让内核使用前224M内存,忽略其余的内存。

这样,我们就有了32M的内存可用,内存起始物理地址为224*1024*1024。

在内核态,通过ioremap,就可以将此物理地址处的内存映射到内核空间。

不过,这种方法好像在X86_64架构下会有问题。在arm上,则没有发现问题。

有高手知道原因,还望指导一下^_^


(b)直接从内核申请一块内存

通过__get_free_pages(GFP_KERNEL,n); 从内核申请n个内存页。n好像必须是2的整数次方。


二、将内存映射到用户空间

通过上面的工作,内核中已经得到了此内存的虚拟地址,当然这是内核空间的虚拟地址。我们假设此地址保存在了void  *rsv_mem变量中。

接下来把他映射到用户空间。这个工作分两部分。一部分是内核态的工作,一部分是用户态的工作。

1. 内核态的工作

在内核态调用misc_register注册一个设备,此设备的其他方面,我们就不说了。

只说说file_operations中的mmap成员的实现。这个实现很简单,代码如下:

static int soft_wdt_mmap(struct file *filp, struct vm_area_struct *vma)
 {
     unsigned long pfn = (virt_to_phys(rsv_mem) >> PAGE_SHIFT);

     if (remap_pfn_range(vma, vma->vm_start, pfn,
                vma->vm_end - vma->vm_start,
                vma->vm_page_prot))
         return -EAGAIN;

     return 0;
 }


2. 用户态的工作

假设内存大小是8192字节。


    int fd=open("/dev/my_dev", O_RDWR);
    void *ptr_dev_mem==mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

好了,这就完成了用户态的映射了。


内核与用户态程序共享内存的方法

标签:

原文地址:http://blog.csdn.net/crazycoder8848/article/details/44345695

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!