aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-04-14 13:37:25 -0700
committerDenys Vlasenko <vda.linux@googlemail.com>2010-04-14 13:37:25 -0700
commit351ef7188a1a2e2f154bbda6f703c2d3f4af6d79 (patch)
tree027081078f4a31f86673d26d85c05afead417df1
parent375a8ef5ea38ea10134c125c75a12bbf9d5ba7bd (diff)
downloadbusybox-w32-351ef7188a1a2e2f154bbda6f703c2d3f4af6d79.tar.gz
busybox-w32-351ef7188a1a2e2f154bbda6f703c2d3f4af6d79.tar.bz2
busybox-w32-351ef7188a1a2e2f154bbda6f703c2d3f4af6d79.zip
devmem: map two pages only if it is necessary
function old new delta devmem_main 463 469 +6 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/devmem.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/miscutils/devmem.c b/miscutils/devmem.c
index e13dedc0a..39b580840 100644
--- a/miscutils/devmem.c
+++ b/miscutils/devmem.c
@@ -13,9 +13,9 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
13 uint64_t read_result; 13 uint64_t read_result;
14 uint64_t writeval = writeval; /* for compiler */ 14 uint64_t writeval = writeval; /* for compiler */
15 off_t target; 15 off_t target;
16 unsigned page_size = getpagesize(); 16 unsigned page_size, mapped_size, offset_in_page;
17 int fd; 17 int fd;
18 int width = 8 * sizeof(int); 18 unsigned width = 8 * sizeof(int);
19 19
20 /* devmem ADDRESS [WIDTH [VALUE]] */ 20 /* devmem ADDRESS [WIDTH [VALUE]] */
21// TODO: options? 21// TODO: options?
@@ -50,15 +50,22 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
50 if (argv[3]) 50 if (argv[3])
51 writeval = bb_strtoull(argv[3], NULL, 0); 51 writeval = bb_strtoull(argv[3], NULL, 0);
52 } else { /* argv[2] == NULL */ 52 } else { /* argv[2] == NULL */
53 /* make argv[3] to be a valid thing to use */ 53 /* make argv[3] to be a valid thing to fetch */
54 argv--; 54 argv--;
55 } 55 }
56 if (errno) 56 if (errno)
57 bb_show_usage(); /* bb_strtouXX failed */ 57 bb_show_usage(); /* one of bb_strtouXX failed */
58 58
59 fd = xopen("/dev/mem", argv[3] ? (O_RDWR | O_SYNC) : (O_RDONLY | O_SYNC)); 59 fd = xopen("/dev/mem", argv[3] ? (O_RDWR | O_SYNC) : (O_RDONLY | O_SYNC));
60 mapped_size = page_size = getpagesize();
61 offset_in_page = (unsigned)target & (page_size - 1);
62 if (offset_in_page + width > page_size) {
63 /* This access spans pages.
64 * Must map two pages to make it possible: */
65 mapped_size *= 2;
66 }
60 map_base = mmap(NULL, 67 map_base = mmap(NULL,
61 page_size * 2 /* in case value spans page */, 68 mapped_size,
62 argv[3] ? (PROT_READ | PROT_WRITE) : PROT_READ, 69 argv[3] ? (PROT_READ | PROT_WRITE) : PROT_READ,
63 MAP_SHARED, 70 MAP_SHARED,
64 fd, 71 fd,
@@ -68,7 +75,7 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
68 75
69// printf("Memory mapped at address %p.\n", map_base); 76// printf("Memory mapped at address %p.\n", map_base);
70 77
71 virt_addr = (char*)map_base + (target & (page_size - 1)); 78 virt_addr = (char*)map_base + offset_in_page;
72 79
73 if (!argv[3]) { 80 if (!argv[3]) {
74 switch (width) { 81 switch (width) {
@@ -119,7 +126,7 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
119 } 126 }
120 127
121 if (ENABLE_FEATURE_CLEAN_UP) { 128 if (ENABLE_FEATURE_CLEAN_UP) {
122 if (munmap(map_base, page_size * 2) == -1) 129 if (munmap(map_base, mapped_size) == -1)
123 bb_perror_msg_and_die("munmap"); 130 bb_perror_msg_and_die("munmap");
124 close(fd); 131 close(fd);
125 } 132 }