1#include <fcntl.h> 2#include <inttypes.h> 3#include <stdbool.h> 4#include <stdio.h> 5#include <stdlib.h> 6#include <string.h> 7#include <sys/mman.h> 8 9#if __LP64__ 10#define strtoptr strtoull 11#else 12#define strtoptr strtoul 13#endif 14 15static int usage() 16{ 17 fprintf(stderr,"r [-b|-s] <address> [<value>]\n"); 18 return -1; 19} 20 21int r_main(int argc, char *argv[]) 22{ 23 if(argc < 2) return usage(); 24 25 int width = 4; 26 if(!strcmp(argv[1], "-b")) { 27 width = 1; 28 argc--; 29 argv++; 30 } else if(!strcmp(argv[1], "-s")) { 31 width = 2; 32 argc--; 33 argv++; 34 } 35 36 if(argc < 2) return usage(); 37 uintptr_t addr = strtoptr(argv[1], 0, 16); 38 39 uintptr_t endaddr = 0; 40 char* end = strchr(argv[1], '-'); 41 if (end) 42 endaddr = strtoptr(end + 1, 0, 16); 43 44 if (!endaddr) 45 endaddr = addr + width - 1; 46 47 if (endaddr <= addr) { 48 fprintf(stderr, "end address <= start address\n"); 49 return -1; 50 } 51 52 bool set = false; 53 uint32_t value = 0; 54 if(argc > 2) { 55 set = true; 56 value = strtoul(argv[2], 0, 16); 57 } 58 59 int fd = open("/dev/mem", O_RDWR | O_SYNC); 60 if(fd < 0) { 61 fprintf(stderr,"cannot open /dev/mem\n"); 62 return -1; 63 } 64 65 off64_t mmap_start = addr & ~(PAGE_SIZE - 1); 66 size_t mmap_size = endaddr - mmap_start + 1; 67 mmap_size = (mmap_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); 68 69 void* page = mmap64(0, mmap_size, PROT_READ | PROT_WRITE, 70 MAP_SHARED, fd, mmap_start); 71 72 if(page == MAP_FAILED){ 73 fprintf(stderr,"cannot mmap region\n"); 74 return -1; 75 } 76 77 while (addr <= endaddr) { 78 switch(width){ 79 case 4: { 80 uint32_t* x = (uint32_t*) (((uintptr_t) page) + (addr & 4095)); 81 if(set) *x = value; 82 fprintf(stderr,"%08"PRIxPTR": %08x\n", addr, *x); 83 break; 84 } 85 case 2: { 86 uint16_t* x = (uint16_t*) (((uintptr_t) page) + (addr & 4095)); 87 if(set) *x = value; 88 fprintf(stderr,"%08"PRIxPTR": %04x\n", addr, *x); 89 break; 90 } 91 case 1: { 92 uint8_t* x = (uint8_t*) (((uintptr_t) page) + (addr & 4095)); 93 if(set) *x = value; 94 fprintf(stderr,"%08"PRIxPTR": %02x\n", addr, *x); 95 break; 96 } 97 } 98 addr += width; 99 } 100 return 0; 101} 102