写一个读写/dev/mem的示例
以下是一个简单的 /dev/mem
读写示例代码,包含详细注释和安全提示。请注意:直接操作物理内存极其危险,可能导致系统崩溃或硬件损坏,仅用于学习或底层开发。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> #include <errno.h> #include <stdint.h>
#define PAGE_SIZE sysconf(_SC_PAGESIZE) #define PHY_ADDR 0x100000
int main() { int fd; void *map_base; void *virt_addr; uint32_t read_result;
fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd == -1) { perror("open /dev/mem failed"); return EXIT_FAILURE; }
size_t map_size = PAGE_SIZE; off_t map_offset = (off_t)(PHY_ADDR & ~(PAGE_SIZE - 1)); size_t page_offset = PHY_ADDR - map_offset;
map_base = mmap( NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map_offset ); if (map_base == MAP_FAILED) { perror("mmap failed"); close(fd); return EXIT_FAILURE; }
volatile uint32_t *target_addr = (volatile uint32_t *)((char*)map_base + page_offset);
read_result = *target_addr; printf("Original value at 0x%x: 0x%08x\n", PHY_ADDR, read_result);
*target_addr = 0xDEADBEEF; printf("New value written: 0x%08x\n", 0xDEADBEEF);
read_result = *target_addr; printf("Current value: 0x%08x\n", read_result);
if (munmap(map_base, map_size) == -1) { perror("munmap failed"); } close(fd);
return EXIT_SUCCESS; }
|
关键说明
地址选择:
PHY_ADDR
需根据具体硬件手册设置(如外设寄存器地址)。
- 示例使用
0x100000
(典型BIOS区域,仅用于演示,实际可能无权限)。
安全要求:
- 必须使用root权限运行:
sudo ./program
- 内核需启用
/dev/mem
访问(非CONFIG_STRICT_DEVMEM
环境)。
风险警告:
- 错误地址可能导致系统崩溃/数据损坏。
- 避免在关键生产环境使用。
编译命令:
典型输出(取决于目标地址内容)
1 2 3
| Original value at 0x100000: 0x00000000 New value written: 0xdeadbeef Current value: 0xdeadbeef
|
建议在嵌入式开发或内核模块中优先使用更安全的方法(如设备驱动),而非直接操作 /dev/mem
。