您的位置:首页 > 运维架构 > Linux

利用/dev/mem实现用户空间驱动

2015-07-15 10:57 627 查看
/dev/mem是物理内存的全映像,可以用来访问物理内存,一般用法是open("/dev/mem",O_RDWR|O_SYNC),然后mmap,接着就可以用mmap的地址来访问物理内存,这实际上就是实现用户空间驱动的一种方法。

它的好处参见博文:http://blog.csdn.net/gujintong1110/article/details/46684589

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

unsigned long phymem_get(unsigned long addr)
{
int fd;
void *map_base, *virt_addr;
unsigned long val;

if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
printf("open /dev/mem failed\n");
return 0;
}

/* Map one page */ //将内核空间映射到用户空间
map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~MAP_MASK);
if(map_base == (void *) -1) {
printf("memory map failed\n");
close(fd);
return 0;
}

virt_addr = map_base + (addr & MAP_MASK);

val = *((unsigned long *) virt_addr);

if(munmap(map_base, MAP_SIZE) == -1) {
printf(" memory unmap failed\n");
close(fd);
return 0;
}
close(fd);
return val;
}

int phymem_set(unsigned long addr,unsigned long val)
{
int fd;
void *map_base, *virt_addr;

if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
printf("open /dev/mem failed\n");
return -1;
}

/* Map one page */ //将内核空间映射到用户空间
map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~MAP_MASK);
if(map_base == (void *) -1) {
printf("memory map failed\n");
close(fd);
return -1;
}

virt_addr = map_base + (addr & MAP_MASK);

*((unsigned long *) virt_addr) = val;

if(munmap(map_base, MAP_SIZE) == -1) {
printf("memory unmap failed\n");
close(fd);
return -1;
}
close(fd);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux 驱动