2 * Simple app. to do memory accesses via /dev/mem.
5 * Copyright (c) Richard Hirst <rhirst@linuxcare.com>
6 * Copyright (c) Thomas Langer <thomas.langer@infineon.com>
15 #include <sys/types.h>
29 "Raw memory i/o utility - $Revision: 2.0 $\n\n"
30 "%s -v -1|2|4 -r|w|a|o [-l <len>] [-f <file>] <addr> [<value>]\n\n"
31 " -v Verbose, asks for confirmation\n"
32 " -1|2|4 Sets memory access size in bytes (default byte)\n"
33 " -l <len> Length in bytes of area to access (defaults to\n"
34 " one access, or whole file length)\n"
35 " -r|w|a|o Read from or Write to memory (default read)\n"
36 " optional write with modify (and/or)\n"
37 " -f <file> File to write on memory read, or\n"
38 " to read on memory write\n"
39 " <addr> The memory address to access\n"
40 " <val> The value to write (implies -w)\n\n"
42 " %s 0x1000 Reads one byte from 0x1000\n"
43 " %s 0x1000 0x12 Writes 0x12 to location 0x1000\n"
44 " %s -2 -l 8 0x1000 Reads 8 words from 0x1000\n"
45 " %s -r -f dmp -l 100 200 Reads 100 bytes from addr 200 to file\n"
46 " %s -w -f img 0x10000 Writes the whole of file to memory\n"
48 "Note access size (-1|2|4) does not apply to file based accesses.\n\n",
49 argv0
, argv0
, argv0
, argv0
, argv0
, argv0
);
55 memread_memory(unsigned long phys_addr
, void *addr
, int len
, int iosize
)
60 printf("%08lx: ", phys_addr
);
62 while (i
< 16 && len
) {
65 printf(" %02x", *(unsigned char *)addr
);
68 printf(" %04x", *(unsigned short *)addr
);
71 printf(" %08lx", *(unsigned long *)addr
);
85 write_memory(unsigned long phys_addr
, void *addr
, int len
, int iosize
, unsigned long value
)
90 *(unsigned char *)addr
= value
;
97 *(unsigned short *)addr
= value
;
104 *(unsigned long *)addr
= value
;
114 and_write_memory(unsigned long phys_addr
, void *addr
, int len
, int iosize
, unsigned long value
)
119 *(unsigned char *)addr
&= value
;
126 *(unsigned short *)addr
&= value
;
133 *(unsigned long *)addr
&= value
;
143 or_write_memory(unsigned long phys_addr
, void *addr
, int len
, int iosize
, unsigned long value
)
148 *(unsigned char *)addr
|= value
;
155 *(unsigned short *)addr
|= value
;
162 *(unsigned long *)addr
|= value
;
172 main (int argc
, char **argv
)
174 int mfd
, ffd
= 0, req_len
= 0, opt
;
176 unsigned long real_len
, real_addr
, req_addr
, req_value
= 0, offset
;
178 int memfunc
= MEM_READ
;
180 char *filename
= NULL
;
187 while ((opt
= getopt(argc
, argv
, "hv124rwaol:f:")) > 0) {
212 req_len
= strtoul(optarg
, &endptr
, 0);
214 fprintf(stderr
, "Bad <size> value '%s'\n", optarg
);
219 filename
= strdup(optarg
);
222 fprintf(stderr
, "Unknown option: %c\n", opt
);
227 if (optind
== argc
) {
228 fprintf(stderr
, "No address given\n");
231 req_addr
= strtoul(argv
[optind
], &endptr
, 0);
233 fprintf(stderr
, "Bad <addr> value '%s'\n", argv
[optind
]);
237 if (!filename
&& (memfunc
== MEM_READ
) && optind
< argc
) {
240 if (filename
&& optind
> argc
) {
241 fprintf(stderr
, "Filename AND value given\n");
244 if (!filename
&& (memfunc
!= MEM_READ
) && optind
== argc
) {
245 fprintf(stderr
, "No value given for WRITE\n");
248 if (!filename
&& (memfunc
!= MEM_READ
)) {
249 req_value
= strtoul(argv
[optind
], &endptr
, 0);
251 fprintf(stderr
, "Bad <value> value '%s'\n", argv
[optind
]);
254 if ((iosize
== 1 && (req_value
& 0xffffff00)) ||
255 (iosize
== 2 && (req_value
& 0xffff0000))) {
256 fprintf(stderr
, "<value> too large\n");
261 if (filename
&& (memfunc
== MEM_READ
) && !req_len
) {
262 fprintf(stderr
, "No size given for file memread\n");
266 fprintf(stderr
, "Too many arguments '%s'...\n", argv
[optind
]);
269 if (filename
&& (memfunc
== MEM_READ
)) {
270 ffd
= open(filename
, O_WRONLY
|O_CREAT
|O_TRUNC
, S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IROTH
);
272 fprintf(stderr
, "Failed to open destination file '%s': %s\n", filename
, strerror(errno
));
276 if (filename
&& (memfunc
!= MEM_READ
)) {
277 ffd
= open(filename
, O_RDONLY
);
279 fprintf(stderr
, "Failed to open source file '%s': %s\n", filename
, strerror(errno
));
284 if (filename
&& !req_len
) {
285 req_len
= lseek(ffd
, 0, SEEK_END
);
287 fprintf(stderr
, "Failed to seek on '%s': %s\n",
288 filename
, strerror(errno
));
291 if (lseek(ffd
, 0, SEEK_SET
)) {
292 fprintf(stderr
, "Failed to seek on '%s': %s\n",
293 filename
, strerror(errno
));
300 if ((iosize
== 2 && (req_addr
& 1)) ||
301 (iosize
== 4 && (req_addr
& 3))) {
302 fprintf(stderr
, "Badly aligned <addr> for access size\n");
305 if ((iosize
== 2 && (req_len
& 1)) ||
306 (iosize
== 4 && (req_len
& 3))) {
307 fprintf(stderr
, "Badly aligned <size> for access size\n");
313 else if (filename
&& (memfunc
== MEM_READ
))
314 printf("Request to read 0x%x bytes from address 0x%08lx\n"
315 "\tto file %s, using %d byte accesses\n",
316 req_len
, req_addr
, filename
, iosize
);
318 printf("Request to write 0x%x bytes to address 0x%08lx\n"
319 "\tfrom file %s, using %d byte accesses\n",
320 req_len
, req_addr
, filename
, iosize
);
321 else if (memfunc
== MEM_READ
)
322 printf("Request to read 0x%x bytes from address 0x%08lx\n"
323 "\tusing %d byte accesses\n",
324 req_len
, req_addr
, iosize
);
326 printf("Request to write 0x%x bytes to address 0x%08lx\n"
327 "\tusing %d byte accesses of value 0x%0*lx\n",
328 req_len
, req_addr
, iosize
, iosize
*2, req_value
);
330 real_addr
= req_addr
& ~4095;
331 if (real_addr
== 0xfffff000) {
332 fprintf(stderr
, "Sorry, cannot map the top 4K page\n");
335 offset
= req_addr
- real_addr
;
336 real_len
= req_len
+ offset
;
337 real_len
= (real_len
+ 4095) & ~ 4095;
338 if (real_addr
+ real_len
< real_addr
) {
339 fprintf(stderr
, "Aligned addr+len exceeds top of address space\n");
343 printf("Attempting to map 0x%lx bytes at address 0x%08lx\n",
344 real_len
, real_addr
);
346 mfd
= open("/dev/mem", (memfunc
== MEM_READ
) ? O_RDONLY
: O_RDWR
);
348 perror("open /dev/mem");
352 printf("open(/dev/mem) ok\n");
353 real_io
= mmap(NULL
, real_len
,
354 (memfunc
== MEM_READ
) ? PROT_READ
:PROT_READ
|PROT_WRITE
,
355 MAP_SHARED
, mfd
, real_addr
);
356 if (real_io
== (void *)(-1)) {
357 fprintf(stderr
, "mmap() failed: %s\n", strerror(errno
));
361 printf("mmap() ok\n");
369 if (c
!= 'y' && c
!= 'Y') {
375 if (filename
&& (memfunc
== MEM_READ
)) {
376 int n
= write(ffd
, real_io
+ offset
, req_len
);
379 fprintf(stderr
, "File write failed: %s\n", strerror(errno
));
382 else if (n
!= req_len
) {
383 fprintf(stderr
, "Only wrote %d of %d bytes to file\n",
389 int n
= read(ffd
, real_io
+ offset
, req_len
);
392 fprintf(stderr
, "File read failed: %s\n", strerror(errno
));
395 else if (n
!= req_len
) {
396 fprintf(stderr
, "Only read %d of %d bytes from file\n",
405 memread_memory(req_addr
, real_io
+ offset
, req_len
, iosize
);
408 write_memory(req_addr
, real_io
+ offset
, req_len
, iosize
, req_value
);
411 and_write_memory(req_addr
, real_io
+ offset
, req_len
, iosize
, req_value
);
414 or_write_memory(req_addr
, real_io
+ offset
, req_len
, iosize
, req_value
);