Linux 下面对物理地址的访问
参考链接:http://zhuhaibobb.blog.163.com/blog/static/2744006720101049030606/
Linux内核提供了/dev/mem驱动,提供了一种直接访问内存物理地址的方法,具体实施有两种方法,一是设备驱动,二是系统调用的方法。
/dev/mem驱动的源文件在drivers/char/mem.c中。这个文件还生成了一些常用的字符设备驱动,表现为/dev/zero,/dev/null等一些特殊的字符设备驱动。cat /dev/mem时,显示的是所有物理内存的地址以及内容信息,通常情况下,只有root用户对其有读写权限。
1. 像使用普通字符设备驱动一样使用/dev/mem.
2. 通过hexedit工具来直接查看/dev/mem,结果如下图:
最左边显示的是物理地址,右边的以4个字节为一组,一行4组,共16个字节。最右边显示的是各内存字节单元内容的ASCII码对于的字符信息。这个文件可以直接修改,按下tab键进入修改模式,按下F2键保存修改内容,修改实时生效。
3. 既然/dev/mem内是全部的内存信息,通过mmap系统调用,将物理内存地址映射到进程的地址空间,从而实现对内存物理地址的读写。
介绍一下,mmap系统调用。
addr:欲映射到地址空间的起始地址,通常设置为NULL,表示让系统自动选定。
length:想要映射的文件大小,以字节为单位。
prot:映射区域的保护方式,有以下几种。
PROT_EXEC:映射区域可执行。
PROT_READ: 映射区域可读。
PROT_WRITE:映射区域科学
PROT_NONE :映射区域不能被访问
flags:映射区域的一些特性,有以下几种。
MAP_FIXED 如果映射不成功则出错返回,
MAP_SHARED 对映射区域的写入数据会写回到原来的文件
MAP_PRIVATE 对映射区域的写入数据不会写回原来的文件
MAP_ANONYMOUS
MAP_DENYWRITE 只允许对映射区域的写入操作,其他对文件直接写入的操作将被拒绝
MAP_LOCKED 锁定映射区域
fd: open返回的文件描述符
offset:被映射文件的偏移量,表示从文件的哪个地方开始映射,一般设置为0.offset必须为4K的整数倍。
例子:要读取物理地址为0x35004000为基地址的,偏移为0x20的内容。fd为打开/dev/mem的文件描述符。ALLOC_SIZE为 1024.
map_base = mmap(0, ALLOC_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x35004000);
type = READ_REG32(map_base + 0x20);
- ///….TO do what you want.
- close(fd);
- munmap(map_base, ALLOC_SIZE);
采用这种方法,可以实现用户空间的驱动。