利用/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;
}
它的好处参见博文: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 socket 初步
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- 基于 Linux 集群环境上 GPFS 的问题诊断
- 谁是桌面王者?Win PK Linux三大镇山之宝
- vivi下重新调整分区
- Linux VS Unix:Linux欲一统天下 Unix不死
- linux下设定环境变量
- Linux下修改MySQL编码的方法