Using devmem for Linux Kernel Debugging¶
How to inspect and modify memory-mapped registers safely with devmem during low-level debugging.
This English edition keeps the original illustrations and reproducible command or configuration examples.


Commands and configuration¶
Usage: devmem ADDRESS [WIDTH [VALUE]]
Read/write from physical address
ADDRESS Address to act upon
WIDTH Width (8/16/...)
VALUE Data to be written
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#define BASE_ADDRESS 0x12345678 // 替换为你要访问的基地址
#define REGISTER_OFFSET 0x04 // 替换为你要访问的寄存器相对于基地址的偏移量
int main() {
int mem_fd;
void *mapped_base, *mapped_dev_base;
off_t dev_base = BASE_ADDRESS;
// 打开 /dev/mem 设备文件
mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (mem_fd == -1) {
perror("Error opening /dev/mem");
return EXIT_FAILURE;
}
// 映射物理地址到用户空间
mapped_base = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, dev_base & ~(getpagesize() - 1));
if (mapped_base == (void *)-1) {
perror("Error mapping /dev/mem into user space");
close(mem_fd);
return EXIT_FAILURE;
}
// 计算相对于映射基地址的偏移量
mapped_dev_base = mapped_base + (dev_base & (getpagesize() - 1));
// 读取寄存器的值
unsigned int reg_value = *((volatile unsigned int *)(mapped_dev_base + REGISTER_OFFSET));
printf("Current value of the register: 0x%08X\n", reg_value);
// 写入新的值到寄存器
unsigned int new_value = 0xABCD;
*((volatile unsigned int *)(mapped_dev_base + REGISTER_OFFSET)) = new_value;
printf("New value written to the register: 0x%08X\n", new_value);
// 解除映射并关闭文件
if (munmap(mapped_base, getpagesize()) == -1) {
perror("Error unmapping /dev/mem");
}
close(mem_fd);
return EXIT_SUCCESS;
}
Practical notes¶
Test each change on a recoverable target, keep logs from the boot or failure path, and record the exact kernel and userspace versions used in the result.