1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#define FOR_devmem
18#include "toys.h"
19
20void devmem_main(void)
21{
22 int writing = toys.optc == 3, page_size = sysconf(_SC_PAGESIZE), bytes = 4,fd;
23 unsigned long long data = 0, map_off, map_len;
24 unsigned long addr = atolx(*toys.optargs);
25 void *map, *p;
26
27
28 if (toys.optc>1) {
29 int i;
30
31 if ((i=stridx("1248", *toys.optargs[1]))==-1 || toys.optargs[1][1])
32 error_exit("bad width: %s", toys.optargs[1]);
33 bytes = 1<<i;
34 }
35
36
37 if (writing) data = atolx_range(toys.optargs[2], 0, (1ULL<<(8*bytes))-1);
38
39
40 if (CFG_TOYBOX_FORK) {
41 fd = xopen("/dev/mem", (writing ? O_RDWR : O_RDONLY) | O_SYNC);
42
43 map_off = addr & ~(page_size - 1);
44 map_len = (addr+bytes-map_off);
45 map = xmmap(0, map_len, writing ? PROT_WRITE : PROT_READ, MAP_SHARED, fd,
46 map_off);
47 p = map + (addr & (page_size - 1));
48 close(fd);
49 } else p = (void *)addr;
50
51
52 if (writing) {
53 if (bytes == 1) *(unsigned char *)p = data;
54 else if (bytes == 2) *(unsigned short *)p = data;
55 else if (bytes == 4) *(unsigned int *)p = data;
56 else if (bytes == 8) *(unsigned long long *)p = data;
57 } else {
58 if (bytes == 1) data = *(unsigned char *)p;
59 else if (bytes == 2) data = *(unsigned short *)p;
60 else if (bytes == 4) data = *(unsigned int *)p;
61 else if (bytes == 8) data = *(unsigned long long *)p;
62 printf((!strchr(*toys.optargs, 'x')) ? "%0*lld\n" : "0x%0*llx\n",
63 bytes*2, data);
64 }
65
66 if (CFG_TOYBOX_FORK) munmap(map, map_len);
67}
68