aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2020-11-08 09:35:05 -0600
committerRob Landley <rob@landley.net>2020-11-08 09:35:05 -0600
commit54e2cd704fb44b8e87bc4507ee852f22eeedfbe9 (patch)
treeb3de46a6ec6435e039b1d5271c659bb11b8a82ca
parente1a5111cbbfe18707fb26a65ed7af654f30a132c (diff)
downloadtoybox-54e2cd704fb44b8e87bc4507ee852f22eeedfbe9.tar.gz
Teach devmem about nommu and 0x prefix on address. Print hex or decimal
output depending on whether address was hex or decimal.
-rw-r--r--toys/other/devmem.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/toys/other/devmem.c b/toys/other/devmem.c
index ced6c518..920d8563 100644
--- a/toys/other/devmem.c
+++ b/toys/other/devmem.c
@@ -10,9 +10,8 @@ config DEVMEM
help
usage: devmem ADDR [WIDTH [DATA]]
- Read/write physical address via /dev/mem.
-
- WIDTH is 1, 2, 4, or 8 bytes (default 4).
+ Read/write physical address. WIDTH is 1, 2, 4, or 8 bytes (default 4).
+ Prefix ADDR with 0x for hexadecimal, output is in same base as address.
*/
#define FOR_devmem
@@ -21,14 +20,15 @@ config DEVMEM
void devmem_main(void)
{
int writing = toys.optc == 3, page_size = sysconf(_SC_PAGESIZE), bytes = 4,fd;
- unsigned long long addr = atolx(toys.optargs[0]), data = 0, map_off, map_len;
+ unsigned long long data = 0, map_off, map_len;
+ unsigned long addr = atolx(*toys.optargs);
void *map, *p;
// WIDTH?
if (toys.optc>1) {
int i;
- if (strlen(toys.optargs[1])!=1 || (i=stridx("1248", *toys.optargs[1]))==-1)
+ if ((i=stridx("1248", *toys.optargs[1]))==-1 || toys.optargs[1][1])
error_exit("bad width: %s", toys.optargs[1]);
bytes = 1<<i;
}
@@ -37,13 +37,16 @@ void devmem_main(void)
if (writing) data = atolx_range(toys.optargs[2], 0, (1ULL<<(8*bytes))-1);
// Map in just enough.
- fd = xopen("/dev/mem", (writing ? O_RDWR : O_RDONLY) | O_SYNC);
- map_off = addr & ~(page_size - 1);
- map_len = (addr+bytes-map_off);
- map = xmmap(NULL, map_len, writing ? PROT_WRITE : PROT_READ, MAP_SHARED, fd,
- map_off);
- p = map + (addr & (page_size - 1));
- close(fd);
+ if (CFG_TOYBOX_FORK) {
+ fd = xopen("/dev/mem", (writing ? O_RDWR : O_RDONLY) | O_SYNC);
+
+ map_off = addr & ~(page_size - 1);
+ map_len = (addr+bytes-map_off);
+ map = xmmap(0, map_len, writing ? PROT_WRITE : PROT_READ, MAP_SHARED, fd,
+ map_off);
+ p = map + (addr & (page_size - 1));
+ close(fd);
+ } else p = (void *)addr;
// Not using peek()/poke() because registers care about size of read/write
if (writing) {
@@ -56,8 +59,9 @@ void devmem_main(void)
else if (bytes == 2) data = *(unsigned short *)p;
else if (bytes == 4) data = *(unsigned int *)p;
else if (bytes == 8) data = *(unsigned long long *)p;
- printf("%#0*llx\n", bytes*2, data);
+ printf((!strchr(*toys.optargs, 'x')) ? "%0*lld\n" : "0x%0*llx\n",
+ bytes*2, data);
}
- munmap(map, map_len);
+ if (CFG_TOYBOX_FORK) munmap(map, map_len);
}