一、首先获取一块物理上连续的物理内存
有多种方法。
(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,

本文探讨了两种方法实现内核与用户态程序共享内存:通过预留内存或直接从内核申请。详细解释了如何在内核态获取物理连续内存,使用ioremap映射,以及通过misc_register注册设备并实现mmap。在用户态,通过open、mmap完成映射。此外,文章提到了应用示例,如生产者-消费者模型,涉及内核态的buffer池、队列、poll函数、ioctl接口和生产者线程的实现。
最低0.47元/天 解锁文章
2612

被折叠的 条评论
为什么被折叠?



