mmap映射物理内存到用户空间的方法

在内核申请一片物理内存,映射到用户空间使用的方法。环境:Linux ubuntu 4.10.0-42-generic。

#include <linux/init.h>  
#include <linux/kernel.h>  
#include <linux/module.h>  
#include <linux/fs.h>  
#include <linux/types.h>  
#include <linux/errno.h>  
#include <linux/fcntl.h>  
#include <linux/vmalloc.h>  
#include <asm/uaccess.h>  
#include <asm/io.h>  
#include <asm/page.h>  
#include <linux/mm.h>  
#include <linux/platform_device.h>  
#include <linux/device.h>  
#include <linux/moduleparam.h>  
#include <linux/cdev.h>  
#include <linux/slab.h> 
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/device.h>

  
#define MMAPIOMEM_DEV_NAME "mmapiomem"  
#define MMAPIOMEM_DEV_MAJOR 280  
#define MMAP_BUF_SIZE 0x500  
  
char *mmap_buf_ptr;  

  
int mmapiomem_open(struct inode *inode,struct file *filp)  
{  
    return 0;  
}  
  
int mmapiomem_release(struct inode *inode,struct file *filp)  
{  
    return 0;  
}  
  
int mmapiomem_mmap(struct file *filp,struct vm_area_struct *vma)  
{  
  
    int result;  
    unsigned long page;
  
    //vma->vm_flags|=VM_RESERVED|VM_SHARED; 
    vma->vm_flags |= (VM_IO | VM_LOCKED | (VM_DONTEXPAND | VM_DONTDUMP)); 
  
    vma->vm_flag
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 中,可以使用 mmap() 系统调用将文件或设备映射到进程的虚拟地址空间,也可以将物理地址映射到进程的虚拟地址空间。要将物理地址 0x860000000 映射到进程的虚拟地址空间,可以执行以下步骤: 1. 打开 /dev/mem 设备文件,这个文件提供了对系统物理内存的访问。 2. 使用 mmap() 系统调用将物理地址 0x860000000 映射到进程的虚拟地址空间中,可以使用如下代码: ```c #define MAP_SIZE 4096UL #define MAP_MASK (MAP_SIZE - 1) off_t physical_address = 0x860000000; int fd = open("/dev/mem", O_RDWR | O_SYNC); void *map_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, physical_address & ~MAP_MASK); ``` 这段代码使用了 MAP_SHARED 标志,表示多个进程可以共享这个映射区域。映射区域的大小为 MAP_SIZE,这里设置为 4096 字节,也就是一个页的大小。MAP_MASK 宏用于掩码,将物理地址的低 12 位清零,因为一个页的大小通常是 4KB,即低 12 位都是 0。 3. 映射成功后,可以通过指针对映射区域进行读写操作,如下所示: ```c volatile uint32_t *mapped_device = (volatile uint32_t *) (map_base + (physical_address & MAP_MASK)); uint32_t value = *mapped_device; *mapped_device = 0x12345678; ``` 这里将映射区域的起始地址加上物理地址的低 12 位,得到了物理地址对应的虚拟地址。用指针指向这个虚拟地址就可以进行读写操作了。注意,这里使用了 volatile 关键字,用于告诉编译器不要对指针所指向的内存进行优化,以保证操作的原子性和可见性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值