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