1. devmem 方式
root@raspberrypi:/home/niyu# busybox devmem 0x7e215000 8 0xa
root@raspberrypi:/home/niyu# busybox devmem 0x7e215000 8
0x0A
root@raspberrypi:/home/niyu# busybox devmem 0x7e215000 8 0xb
root@raspberrypi:/home/niyu# busybox devmem 0x7e215000 8
0x0B
2. kgdb 方式
[3]kdb> mdp 0x7e215000 1
phys 0x000000007e215000 000000000000000b ffffffbf00215008 .........P!....
3. devmem 方式备注:
3.1 kernel 配置
配置 CONFIG_STRICT_DEVMEM= n
否则会出现如下错误
root@raspberrypi:/usr# sudo busybox devmem 0x7e204000
devmem: mmap: Operation not permitted
3.2 devmem 制作
制作方法一. 基于busybox
下载
wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2
tar xf busybox-1.35.0.tar.bz2;cd busybox-1.35.0/
配置
make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 menuconfig -j32
修改为静态连接 Settings [*] Build static binary (no shared libs)
安装
make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 install -j32
使用
busybox devmem 0x7e204000
制作方法2: 手动交叉编译
aarch64-linux-gnu-gcc devmem.c -o devmem
/*devmem.c*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <stdint.h>// 定义映射大小和对齐掩码
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)int main(int argc, char **argv) {if (argc < 2) {fprintf(stderr, "Usage: %s <physical_address> [value_to_write]\n", argv[0]);return 1;}// 解析地址和可选的写入值unsigned long target = strtoul(argv[1], NULL, 0);unsigned int write_val = 0;int do_write = 0;if (argc > 2) {write_val = strtoul(argv[2], NULL, 0);do_write = 1;}// 打开 /dev/memint fd = open("/dev/mem", O_RDWR | O_SYNC);if (fd < 0) {perror("Can't open /dev/mem");return 1;}// 映射目标物理地址void *map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);if (map_base == (void *) -1) {perror("Memory map failed");close(fd);return 1;}// 计算指针偏移以访问目标地址void *virt_addr = (char *)map_base + (target & MAP_MASK);unsigned long read_result = *((unsigned long *)virt_addr);// 打印读取的值printf("Value at address 0x%lX (%p): 0x%lX\n", target, virt_addr, read_result);// 如果提供了值参数,则写入if (do_write) {*((unsigned long *)virt_addr) = write_val;printf("Written 0x%X to address 0x%lX (%p)\n", write_val, target, virt_addr);}// 清理资源if (munmap(map_base, MAP_SIZE) == -1) {perror("Memory unmap failed");}close(fd);return 0;
}
4. kgdb 方式备注
进入kgdb
echo "ttyS0,115200" > /sys/module/kgdboc/parameters/kgdboc
echo g > /proc/sysrq-trigger;
退出kgdb
[3]kdb> go
root@raspberrypi:/home/niyu#