Linux下访问内存物理地址_第1页
Linux下访问内存物理地址_第2页
Linux下访问内存物理地址_第3页
Linux下访问内存物理地址_第4页
Linux下访问内存物理地址_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Linux下访问内存物理地址bytmsonhsut2008.4.28Linux内核里提供的/dev/mem驱动,为我们读写内存物理地址,提供了一个渠道。下面讲述2种利用mem设备文件进行物理地址读写的方法,一种是设备驱动的方法,另一种是系统调用的方法。首先我们看下mem这个设备文件,/dev/mem是linux下的一个字符设备,源文件是/drivers/char/mem.c,这个设备文件是专门用来读写物理地址用的。里面的内容是所有物理内存的地址以及内容信息。通常只有root用户对其有读写权限。1.设备驱动的方法下面是mem.c文件里定义的file_operations结构,提供了llseek,

2、read,write,mmap以及open等方法。staticstructfile_operationsmem_fops=.llseek=memory_lseek,.read=read_mem,.write=write_mem,.mmap=mmap_mem,.open=open_mem,;因此我们可以通过一般驱动的使用方法,将内存完全当作一个设备来对对待。应用程序如下:#include#includeintmain(void)intfd;char*rdbuf;char*wrbuf=butterfly;inti;fd=open(/dev/mem,O_RDWR);if(fd0)printf(ope

3、n/dev/memfailed.);read(fd,rdbuf,10);for(i=0;i10;i+)printf(oldmem%d:%cn,i,*(rdbuf+i);lseek(fd,5,0);write(fd,wrbuf,10);lseek(fd,0,0);/movef_opstothefrontread(fd,rdbuf,10);for(i=0;i10;i+)printf(newmem%d:%cn,i,*(rdbuf+i);return0;执行结果如下:将内存最开始10个字节的内容进行替换rootVOIP-IPCAMapp#./memtestoldmem0:boldmem1:uoldme

4、m2:toldmem3:toldmem4:eoldmem5:roldmem6:foldmem7:loldmem8:yoldmem9:!newmem0:bnewmem1:unewmem2:tnewmem3:tnewmem4:enewmem5:bnewmem6:unewmem7:tnewmem8:tnewmem9:e2.系统调用的方法细心的你可能会发现,既然你前面说了这个文件里存放的就是内存的地址及内容信息,那我可不可以直接查看到呢,答案是:可以的。linux内核的开发者为我们提供了一个命令hexedit,通过它就可以将/dev/mem的内容显示出来(如果你使用cat/dev/mem将会看到乱码)

5、,执行hexedit/dev/mem的结果如下:000000006275747465627574746572666C792120butterfly!00000010202020202020202020202020202020200000002020202020202020202020202020202020000000306FEF00F06FEF00F057EF00F06FEF00F0o.o.W.o.00000040021100C04DF800F041F800F0348500F0M.A.4.0000005039E700F059F800F02EE800F0D2EF00F09.Y00000060A

6、4E700F0F2E600F06EFE00F053FF00F0n.S.0000007053FF00F0A4F000F0C7EF00F01C4200C0SB.从上图可见,最左边显示的是地址,接下来24列显示的是各内存字节单元内容的ASCII码信息,最右边显示的是对应的字符信息。让人欣慰的是,这个文件可以直接修改,按下tab键进入修改模式,修改过程中修改内容会以粗体显示,按下F2保存后粗体消失。上面的butterfly就是通过这种方式修改的。既然内存的地址以及内容信息全部被保存在mem这个设备文件里,那么我们可以想到通过另外一种方式来实现对物理地址的读写了。那就是将mem设备文件和mmap系统调用

7、结合起来使用,将文件里的物理内存地址映射到进程的地址空间,从而实现对内存物理地址的读写。下面谈一下mmap系统调用。mmap的函数原型为:void*mmap(void*start,size_tlength,intprot,intflags,intfd,off_toffset),该函数定义在/usr/include/sys/mman.h中,使用时要包含:#include,mmap()用来将某个文件中的内容映射到进程的地址空间,对该空间的存取即是对该文件内容的读写。参数说明如下:start:指向欲映射到的地址空间的起始地址,通常设为null或者0.表示让系统融自动选定地址,映射成功后该地址会返回。

8、length:表示映射的文件内容的大小,以字节为单位。prot:表示映射区域的保护方式,有如下四种组合:-PROT_EXEC映射区域可执行,-PROT_READ映射区域可读,-PROT_WRITE映射区域可写,-PROT_NONE映射区域不能被访问flags:映射区域的一些特性,主要有:-MAP_FIXED如果映射不成功则出错返回,-MAP_SHARED对映射区域的写入数据会写回到原来的文件-MAP_PRIVATE对映射区域的写入数据不会写回原来的文件-MAP_ANONYMOUS-MAP_DENYWRITE只允许对映射区域的写入操作,其他对文件直接写入的操作将被拒绝-MAP_LOCKED锁定映

9、射区域在调用mmap()时,必须要指定MAP_SHARED或MAP_PRIVATE。fd:open()返回的文件描述符。offset:为被映射文件的偏移量,表示从文件的哪个地方开始映射,一般设置为0,表示从文件的最开始位置开始映射。offset必须是分页大小(4096字节)的整数倍。应用程序如下:#include#include#include/mmapheadfileintmain(void)inti;intfd;char*start;char*buf=butterfly!;/open/dev/memwithreadandwritemodefd=open(/dev/mem,O_RDWR);i

10、f(fd0)printf(cannotopen/dev/mem.);return-1;/mapphysicalmemory0-10bytesstart=(char*)mmap(0,10,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);if(start0)printf(mmapfailed.);return-1;/Readoldvaluefor(i=0;i10;i+)printf(oldmem%d:%cn,i,*(start+i);/writememorymemcpy(start,buf,10);/Readnewvaluefor(i=0;i10;i+)printf(newmem%d:%cn,i,*(start+i);munmap(start,10);/destroymapmemoryclose(fd);/closefilereturn0;程序执行结果如下:rootVOIP-IPCAMapp#./rwphyoldmem0:boldmem1:uoldmem2:toldmem3:toldmem4:eoldmem5:boldmem6:uoldmem7:toldmem8:toldmem9:enewmem0:bnewmem1:unewmem2:tnewmem

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论