LINUX

linux读写物理内存

日期:2015/6/28来源: IT猫扑网

  一、基础知识:

  1. 设备文件:

  mem是一个字符设备文件,是计算机主存的一个影象。通常只有root用户对其有读写权限。因此只有root用户能进行这些操作。

  如果要打开设备文件/dev/mem,需要系统调用open()函数,作用是打开一个文件或设备,其函数原型 为:

  #include <fcntl.h>

  #include <stat,h>

  int open(const char *path, int flags);

  open 函数定义在/usr/include/fcntl.h中;如果操作成功则返回一个文件描述符,否则返回-1;其中path是被打开文件的路径即文件名描 述;flags是文件的访问模式描述,可常用的选项见下表:

  flags的取值及其含义 flags  含义

  O_RDONLY    只读方式

  O_WRONLY   只写方式

  O_RDWR  可读写方式

  2.内存映像:

  内存映像其实在内存中创建一个与外存中文件完全相同的映像。用户可以将整个文件映射到内存中,也可以将文件的一部分映射到内存中。使用操作内存的方法对文 件进行操作。系统会将内存映像文件所做的改动反映到真实文件中去。

  在内存映像I/O的实现过程中需要用到一些系统调用:

  首先是创建内存映像文件的系统调用mmap()函数,其函数原型为:

  #include <sys/types.h>

  #include <sys/mman.h>

  void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset);   mmap函数定义在/usr/include/sys/mman.h中;

  此函数用于将一个文件或它的一部分映射到内存中。参数start是一个void指针,表示希望将文件映射到此指针指向的位置,通常为NULL;参数 length定义内存映像文件所占用的内存空间大小,以字节计;参数prot表示内存映像文件的安全属性,它的可使用的选项见表1,注意和open函数中 的flags属性保持一致;参数flags是内存映像的标志,相关的标志见表2;参数fd是要映射的文件的描述符;参数offset表示所映射的数据内容 距离文件头的偏移量。

  当调用成功时,返回值为指向内存映像起始地址的指针;当调用失败时,返回值为-1。

  表1 prot的取值及其含义

  prot     含义

  PROT_EXEC 被映像内存可能含义机器码,可被执行

  PROT_NONE 映像内存不允许访问

  PROT_READ 映像内存可读

  PROT_WRITE 映像内存可写

  表2 flags的取值及其含义

  Flags 含义

  MAP_FIXED      若无法在指定位置建立内存映像文件,则出错返回

  MAP_PRIVATE 对内存映像文件所做操作不反映到外存文件中

  MAP_SHARED 对内存映像文件所做操作都将被保存到外存文件中

  另外我们使用完内存映像文件后,要用系统调用函数munmap()函数来撤销,其函数原型为:

  #include <sys/types.h>

  #include <sys/mman.h>

  int munmap(void *start,size_t length);

  参数start表示要撤销的内存映像文件的起始地址;参数length表示要撤销的内存映像文件的大小。调用成功时,返回值为0;调用失败时返回值为 -1,并将errno设置为相应值。

  最后,如果我们要将内存映像的改动保存到外存中,还需要系统调用msync()函数,其函数原型为:

  #include <sys/types.h>

  #include <sys/mman.h>

  int msync(const void *start,size_t length,int flags);

  参数start表示要保存到外存的那些源文件的起始地址;参数length表示内存映像文件的大小;参数flags设置了函数的相应操作,其具体选项见表 3。

  表3 flags的取值及其含义

  flags  含义

  MS_ASYNC   调用一个写操作并返回

  MS_INVALIDATE      映像到相同文件的内存映像数据更新

  MS_SYNC      完成写操作后函数返回

  通过/dev/mem设备文件和mmap系统调用,可以将线性地址描述的物理内存映射到进程的地址空间,然后就可以直 接访问这段内存了。

  二、应用实例:

  1.   源代码:

  /*

  file: read.c

  function: Read the the first 5 bytes of the memory and then Write it with "HELLO"

  */

  #include <stdio.h>

  #include <unistd.h>

  #include <sys/mman.h>

  #include <sys/types.h>

  #include <sys/stat.h>

  #include <fcntl.h>

  int main (int args, char* arg[])

  {

  int i;

  int fd;

  char* mem;

  char *buff = "HELLO";

  //open /dev/mem with read and write mode

  if ((fd = open ("/dev/mem", O_RDWR)) < 0)

  {

  perror ("open error");

  return -1;

  }

  //map physical memory 0-10 bytes

  mem = mmap (0, 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

  if (mem == MAP_FAILED) {

  perror ("mmap error:");

  return 1;

  }

  //Read old value

  for (i = 0; i < 5; i++)

  {

  printf("\nold mem[%d]:%d", i, mem[i]);

  }

  //write memory

  memcpy(mem, buff, 5);

  //Read new value

  for (i = 0; i<5 ; i++)

  {

  printf("\nnew mem[%d]:%c", i, mem[i]);

  }

  printf("\n";

  munmap (mem, 10); //destroy map memory

  close (fd);   //close file

  return 0;

  }

  2.编译、运行:

  #gcc -o read read.c

相关文章

相关下载

网友评论

我要评论...
    没有更早的评论了
    取消