2 * Simple app. to do memory accesses via /dev/mem.
6 * Copyright (c) Richard Hirst <rhirst@linuxcare.com>
7 * Copyright (c) Thomas Langer <thomas.langer@infineon.com>
16 #include <sys/types.h>
30 "Raw memory i/o utility - $Revision: 2.0 $\n\n"
31 "%s -v -1|2|4 -r|w|a|o [-l <len>] [-f <file>] <addr> [<value>]\n\n"
32 " -v Verbose, asks for confirmation\n"
33 " -1|2|4 Sets memory access size in bytes (default byte)\n"
34 " -l <len> Length in bytes of area to access (defaults to\n"
35 " one access, or whole file length)\n"
36 " -r|w|a|o Read from or Write to memory (default read)\n"
37 " optional write with modify (and/or)\n"
38 " -f <file> File to write on memory read, or\n"
39 " to read on memory write\n"
40 " <addr> The memory address to access\n"
41 " <val> The value to write (implies -w)\n\n"
43 " %s 0x1000 Reads one byte from 0x1000\n"
44 " %s 0x1000 0x12 Writes 0x12 to location 0x1000\n"
45 " %s -2 -l 8 0x1000 Reads 8 words from 0x1000\n"
46 " %s -r -f dmp -l 100 200 Reads 100 bytes from addr 200 to file\n"
47 " %s -w -f img 0x10000 Writes the whole of file to memory\n"
49 "Note access size (-1|2|4) does not apply to file based accesses.\n\n",
50 argv0
, argv0
, argv0
, argv0
, argv0
, argv0
);
56 memread_memory(unsigned long phys_addr
, void *addr
, int len
, int iosize
)
61 printf("%08lx: ", phys_addr
);
63 while (i
< 16 && len
) {
66 printf(" %02x", *(unsigned char *)addr
);
69 printf(" %04x", *(unsigned short *)addr
);
72 printf(" %08lx", *(unsigned long *)addr
);
86 write_memory(unsigned long phys_addr
, void *addr
, int len
, int iosize
, unsigned long value
)
91 *(unsigned char *)addr
= value
;
98 *(unsigned short *)addr
= value
;
105 *(unsigned long *)addr
= value
;
115 and_write_memory(unsigned long phys_addr
, void *addr
, int len
, int iosize
, unsigned long value
)
120 *(unsigned char *)addr
&= value
;
127 *(unsigned short *)addr
&= value
;
134 *(unsigned long *)addr
&= value
;
144 or_write_memory(unsigned long phys_addr
, void *addr
, int len
, int iosize
, unsigned long value
)
149 *(unsigned char *)addr
|= value
;
156 *(unsigned short *)addr
|= value
;
163 *(unsigned long *)addr
|= value
;
173 main (int argc
, char **argv
)
175 int mfd
, ffd
= 0, req_len
= 0, opt
;
177 unsigned long real_len
, real_addr
, req_addr
, req_value
= 0, offset
;
179 int memfunc
= MEM_READ
;
181 char *filename
= NULL
;
188 while ((opt
= getopt(argc
, argv
, "hv124rwaol:f:")) > 0) {
213 req_len
= strtoul(optarg
, &endptr
, 0);
215 fprintf(stderr
, "Bad <size> value '%s'\n", optarg
);
220 filename
= strdup(optarg
);
223 fprintf(stderr
, "Unknown option: %c\n", opt
);
228 if (optind
== argc
) {
229 fprintf(stderr
, "No address given\n");
232 req_addr
= strtoul(argv
[optind
], &endptr
, 0);
234 fprintf(stderr
, "Bad <addr> value '%s'\n", argv
[optind
]);
238 if (!filename
&& (memfunc
== MEM_READ
) && optind
< argc
) {
241 if (filename
&& optind
> argc
) {
242 fprintf(stderr
, "Filename AND value given\n");
245 if (!filename
&& (memfunc
!= MEM_READ
) && optind
== argc
) {
246 fprintf(stderr
, "No value given for WRITE\n");
249 if (!filename
&& (memfunc
!= MEM_READ
)) {
250 req_value
= strtoul(argv
[optind
], &endptr
, 0);
252 fprintf(stderr
, "Bad <value> value '%s'\n", argv
[optind
]);
255 if ((iosize
== 1 && (req_value
& 0xffffff00)) ||
256 (iosize
== 2 && (req_value
& 0xffff0000))) {
257 fprintf(stderr
, "<value> too large\n");
262 if (filename
&& (memfunc
== MEM_READ
) && !req_len
) {
263 fprintf(stderr
, "No size given for file memread\n");
267 fprintf(stderr
, "Too many arguments '%s'...\n", argv
[optind
]);
270 if (filename
&& (memfunc
== MEM_READ
)) {
271 ffd
= open(filename
, O_WRONLY
|O_CREAT
|O_TRUNC
, S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IROTH
);
273 fprintf(stderr
, "Failed to open destination file '%s': %s\n", filename
, strerror(errno
));
277 if (filename
&& (memfunc
!= MEM_READ
)) {
278 ffd
= open(filename
, O_RDONLY
);
280 fprintf(stderr
, "Failed to open source file '%s': %s\n", filename
, strerror(errno
));
285 if (filename
&& !req_len
) {
286 req_len
= lseek(ffd
, 0, SEEK_END
);
288 fprintf(stderr
, "Failed to seek on '%s': %s\n",
289 filename
, strerror(errno
));
292 if (lseek(ffd
, 0, SEEK_SET
)) {
293 fprintf(stderr
, "Failed to seek on '%s': %s\n",
294 filename
, strerror(errno
));
301 if ((iosize
== 2 && (req_addr
& 1)) ||
302 (iosize
== 4 && (req_addr
& 3))) {
303 fprintf(stderr
, "Badly aligned <addr> for access size\n");
306 if ((iosize
== 2 && (req_len
& 1)) ||
307 (iosize
== 4 && (req_len
& 3))) {
308 fprintf(stderr
, "Badly aligned <size> for access size\n");
314 else if (filename
&& (memfunc
== MEM_READ
))
315 printf("Request to read 0x%x bytes from address 0x%08lx\n"
316 "\tto file %s, using %d byte accesses\n",
317 req_len
, req_addr
, filename
, iosize
);
319 printf("Request to write 0x%x bytes to address 0x%08lx\n"
320 "\tfrom file %s, using %d byte accesses\n",
321 req_len
, req_addr
, filename
, iosize
);
322 else if (memfunc
== MEM_READ
)
323 printf("Request to read 0x%x bytes from address 0x%08lx\n"
324 "\tusing %d byte accesses\n",
325 req_len
, req_addr
, iosize
);
327 printf("Request to write 0x%x bytes to address 0x%08lx\n"
328 "\tusing %d byte accesses of value 0x%0*lx\n",
329 req_len
, req_addr
, iosize
, iosize
*2, req_value
);
331 real_addr
= req_addr
& ~4095;
332 if (real_addr
== 0xfffff000) {
333 fprintf(stderr
, "Sorry, cannot map the top 4K page\n");
336 offset
= req_addr
- real_addr
;
337 real_len
= req_len
+ offset
;
338 real_len
= (real_len
+ 4095) & ~ 4095;
339 if (real_addr
+ real_len
< real_addr
) {
340 fprintf(stderr
, "Aligned addr+len exceeds top of address space\n");
344 printf("Attempting to map 0x%lx bytes at address 0x%08lx\n",
345 real_len
, real_addr
);
347 mfd
= open("/dev/mem", (memfunc
== MEM_READ
) ? O_RDONLY
: O_RDWR
);
349 perror("open /dev/mem");
353 printf("open(/dev/mem) ok\n");
354 real_io
= mmap(NULL
, real_len
,
355 (memfunc
== MEM_READ
) ? PROT_READ
:PROT_READ
|PROT_WRITE
,
356 MAP_SHARED
, mfd
, real_addr
);
357 if (real_io
== (void *)(-1)) {
358 fprintf(stderr
, "mmap() failed: %s\n", strerror(errno
));
362 printf("mmap() ok\n");
370 if (c
!= 'y' && c
!= 'Y') {
376 if (filename
&& (memfunc
== MEM_READ
)) {
377 int n
= write(ffd
, real_io
+ offset
, req_len
);
380 fprintf(stderr
, "File write failed: %s\n", strerror(errno
));
383 else if (n
!= req_len
) {
384 fprintf(stderr
, "Only wrote %d of %d bytes to file\n",
390 int n
= read(ffd
, real_io
+ offset
, req_len
);
393 fprintf(stderr
, "File read failed: %s\n", strerror(errno
));
396 else if (n
!= req_len
) {
397 fprintf(stderr
, "Only read %d of %d bytes from file\n",
406 memread_memory(req_addr
, real_io
+ offset
, req_len
, iosize
);
409 write_memory(req_addr
, real_io
+ offset
, req_len
, iosize
, req_value
);
412 and_write_memory(req_addr
, real_io
+ offset
, req_len
, iosize
, req_value
);
415 or_write_memory(req_addr
, real_io
+ offset
, req_len
, iosize
, req_value
);