Heng30的博客
搜索 分类 关于 订阅

在Linux中通过mem字符设备快速操作物理地址

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是一个强大的工具,适合需要直接访问物理内存的场景,但使用时需格外小心,以免引发系统问题。