2025-02-22
之前写过一篇关于devmem
工具的文章:在Linux中使用devmem快速操作物理地址。这个工具就是通过读写/dev/mem
字符设备来操作物理地址的。但有的时候我们需要通过代码来操作物理地址,那该如何实现呢?
以下C
语言代码展示了,如何通过/dev/mem
读取物理内存。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#define PHYS_ADDR 0x100000 // 示例物理地址
int main(void) {
int fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd == -1) {
perror("open");
return -1;
}
// 映射物理内存
void *map_base = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PHYS_ADDR);
if (map_base == MAP_FAILED) {
perror("mmap");
close(fd);
return -1;
}
// 访问内存
unsigned char *virt_addr = (unsigned char *)map_base;
printf("Value at address 0x%x: 0x%x\n", PHYS_ADDR, *virt_addr);
// 解除映射并关闭文件
munmap(map_base, 4096);
close(fd);
return 0;
}
如果mmap
函数出错,需要检查内核配置,确认是否启用了CONFIG_STRICT_DEVMEM
。
grep CONFIG_STRICT_DEVMEM /boot/config-$(uname -r)
如果输出为CONFIG_STRICT_DEVMEM=y
,则表示已启用。因此mmap
访问受限制的内存区域会出错。可以尝试禁用CONFIG_STRICT_DEVMEM
,然后重新编译内核。具体配置在Kernel hacking
->Filter access to /dev/mem
。
/dev/mem
是一个强大的工具,适合需要直接访问物理内存的场景,但使用时需格外小心,以免引发系统问题。