]>
Commit | Line | Data |
---|---|---|
1 | diff -Nrup include/applets.h include/applets.h | |
2 | --- include/applets.h 2008-04-26 18:22:37.000000000 +0000 | |
3 | +++ include/applets.h 2008-04-26 18:19:53.000000000 +0000 | |
4 | @@ -121,6 +121,7 @@ USE_DEALLOCVT(APPLET(deallocvt, _BB_DIR_ | |
5 | USE_DELGROUP(APPLET_ODDNAME(delgroup, deluser, _BB_DIR_BIN, _BB_SUID_NEVER, delgroup)) | |
6 | USE_DELUSER(APPLET(deluser, _BB_DIR_BIN, _BB_SUID_NEVER)) | |
7 | USE_DEVFSD(APPLET(devfsd, _BB_DIR_SBIN, _BB_SUID_NEVER)) | |
8 | +USE_DEVMEM(APPLET(devmem, _BB_DIR_SBIN, _BB_SUID_NEVER)) | |
9 | USE_DF(APPLET(df, _BB_DIR_BIN, _BB_SUID_NEVER)) | |
10 | USE_APP_DHCPRELAY(APPLET(dhcprelay, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) | |
11 | USE_DIFF(APPLET(diff, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | |
12 | diff -Nrup include/usage.h include/usage.h | |
13 | --- include/usage.h 2007-12-21 22:00:31.000000000 +0000 | |
14 | +++ include/usage.h 2008-04-26 18:21:59.000000000 +0000 | |
15 | @@ -630,6 +630,16 @@ | |
16 | "\n and processing synthetic REGISTER events," \ | |
17 | "\n do not poll for events") | |
18 | ||
19 | +#define devmem_trivial_usage \ | |
20 | + "{ address } [ type [ data ] ]" | |
21 | + | |
22 | +#define devmem_full_usage \ | |
23 | + "Read/Write from physical addresses" \ | |
24 | + "\n\nUsage: devmem { address } [ type [ data ] ]" \ | |
25 | + "\n address : memory address to act upon" \ | |
26 | + "\n type : access operation type : [b]yte, [h]alfword, [w]ord" \ | |
27 | + "\n data : data to be written" | |
28 | + | |
29 | /* -k is accepted but ignored for !HUMAN_READABLE, | |
30 | * but we won't mention this (unimportant) */ | |
31 | #if ENABLE_FEATURE_HUMAN_READABLE || ENABLE_FEATURE_DF_INODE | |
32 | diff -Nrup miscutils/Config.in miscutils/Config.in | |
33 | --- miscutils/Config.in 2007-12-21 22:00:31.000000000 +0000 | |
34 | +++ miscutils/Config.in 2008-04-26 17:54:51.000000000 +0000 | |
35 | @@ -120,6 +120,13 @@ config FEATURE_DEVFS | |
36 | /dev/loop0. If your /dev directory has normal names instead of | |
37 | devfs names, you don't want this. | |
38 | ||
39 | +config DEVMEM | |
40 | + bool "devmem" | |
41 | + default y | |
42 | + help | |
43 | + devmem is a small program that reads and writes from physical | |
44 | + memory using /dev/mem. | |
45 | + | |
46 | config EJECT | |
47 | bool "eject" | |
48 | default n | |
49 | diff -Nrup miscutils/Kbuild miscutils/Kbuild | |
50 | --- miscutils/Kbuild 2007-12-21 22:00:31.000000000 +0000 | |
51 | +++ miscutils/Kbuild 2008-04-26 17:56:36.000000000 +0000 | |
52 | @@ -12,6 +12,7 @@ lib-$(CONFIG_CROND) += crond.o | |
53 | lib-$(CONFIG_CRONTAB) += crontab.o | |
54 | lib-$(CONFIG_DC) += dc.o | |
55 | lib-$(CONFIG_DEVFSD) += devfsd.o | |
56 | +lib-$(CONFIG_DEVMEM) += devmem.o | |
57 | lib-$(CONFIG_EJECT) += eject.o | |
58 | lib-$(CONFIG_HDPARM) += hdparm.o | |
59 | lib-$(CONFIG_LAST) += last.o | |
60 | diff -Nrup miscutils/devmem.c miscutils/devmem.c | |
61 | --- miscutils/devmem.c 1970-01-01 00:00:00.000000000 +0000 | |
62 | +++ miscutils/devmem.c 2008-04-26 18:18:30.000000000 +0000 | |
63 | @@ -0,0 +1,65 @@ | |
64 | +/* | |
65 | + * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. | |
66 | + * Copyright (C) 2000, Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) | |
67 | + * Copyright (C) 2008, BusyBox Team. -solar 4/26/08 | |
68 | + */ | |
69 | + | |
70 | +#include "libbb.h" | |
71 | + | |
72 | +#define DEVMEM_MAP_SIZE 4096UL | |
73 | +#define DEVMEM_MAP_MASK (DEVMEM_MAP_SIZE - 1) | |
74 | + | |
75 | +int devmem_main(int argc, char **argv) { | |
76 | + void *map_base, *virt_addr; | |
77 | + unsigned long read_result, writeval; | |
78 | + off_t target; | |
79 | + int fd, access_type = 'w'; | |
80 | + | |
81 | + if (argc < 2) | |
82 | + bb_show_usage(); | |
83 | + | |
84 | + target = bb_strtoul(argv[1], 0, 0); | |
85 | + | |
86 | + if (argc > 2) | |
87 | + access_type = tolower(argv[2][0]); | |
88 | + | |
89 | + fd = xopen("/dev/mem", O_RDWR | O_SYNC); | |
90 | + | |
91 | + if ((map_base = mmap(0, DEVMEM_MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~DEVMEM_MAP_MASK)) == MAP_FAILED) | |
92 | + bb_perror_msg_and_die("mmap"); | |
93 | + | |
94 | + printf("Memory mapped at address %p.\n", map_base); | |
95 | + | |
96 | + virt_addr = map_base + (target & DEVMEM_MAP_MASK); | |
97 | + if (access_type == 'b') | |
98 | + read_result = *((unsigned char *) virt_addr); | |
99 | + else if (access_type == 'h') | |
100 | + read_result = *((unsigned short *) virt_addr); | |
101 | + else if (access_type == 'w') | |
102 | + read_result = *((unsigned long *) virt_addr); | |
103 | + else { | |
104 | + fprintf(stderr, "Illegal data type '%c'\n", access_type); | |
105 | + exit(EXIT_FAILURE); | |
106 | + } | |
107 | + printf("Value at address 0x%X (%p): 0x%X\n", target, virt_addr, read_result); | |
108 | + | |
109 | + if (argc > 3) { | |
110 | + writeval = bb_strtoul(argv[3], 0, 0); | |
111 | + if (access_type == 'b') { | |
112 | + *((unsigned char *) virt_addr) = writeval; | |
113 | + read_result = *((unsigned char *) virt_addr); | |
114 | + } else if (access_type == 'h') { | |
115 | + *((unsigned short *) virt_addr) = writeval; | |
116 | + read_result = *((unsigned short *) virt_addr); | |
117 | + } else if (access_type == 'w') { | |
118 | + *((unsigned long *) virt_addr) = writeval; | |
119 | + read_result = *((unsigned long *) virt_addr); | |
120 | + } | |
121 | + printf("Written 0x%X; readback 0x%X\n", writeval, read_result); | |
122 | + } | |
123 | + | |
124 | + if (munmap(map_base, DEVMEM_MAP_SIZE) == -1) | |
125 | + bb_perror_msg_and_die("munmap"); | |
126 | + close(fd); | |
127 | + fflush_stdout_and_exit(EXIT_SUCCESS); | |
128 | +} |