[Toybox] [PATCH v2] Support non memory mapped access
Karthikeyan Ramasubramanian
kramasub at google.com
Fri Oct 25 13:40:54 PDT 2024
Add --no-mmap flag to indicate seek and read/write access. This allows
accessing devices that do not support mapping into memory - eg.
/dev/nvram, /dev/msr0 etc.
Also currently only WIDTH bytes are mapped into memory even when more
data is accessed. Fix this by mapping WIDTH * number of data.
Test: ./post_update.sh && m toybox. Push devmem test into DUT and access
/dev/mem through memory mapped access, /dev/nvram & /dev/msr* through
non memory-mapped access. Also update the toybox test cases to include
the non memory mapped access and confirm that all the tests are passing.
PASS: devmem read --no-mmap default (4)
PASS: devmem read --no-mmap 1
PASS: devmem read --no-mmap 2
PASS: devmem read --no-mmap 4
PASS: devmem read --no-mmap 8
PASS: devmem write 1
PASS: devmem write 2
PASS: devmem write 4
PASS: devmem write 8
PASS: devmem write --no-mmap 1
PASS: devmem write --no-mmap 2
PASS: devmem write --no-mmap 4
PASS: devmem write --no-mmap 8
PASS: devmem write 1 multiple
PASS: devmem write 2 multiple
PASS: devmem write 4 multiple
PASS: devmem write 8 multiple
PASS: devmem write --no-mmap 1 multiple
PASS: devmem write --no-mmap 2 multiple
PASS: devmem write --no-mmap 4 multiple
PASS: devmem write --no-mmap 8 multiple
Changelog since v1:
- Removed android specific files
- Removed xlseek after xwrite since xwrite advances the position
- Added test cases for --no-mmap access
---
tests/devmem.test | 18 +++++++++++++++++
toys/other/devmem.c | 47 +++++++++++++++++++++++++++++----------------
2 files changed, 48 insertions(+), 17 deletions(-)
diff --git a/tests/devmem.test b/tests/devmem.test
index 2b16bfd4..9b3ecae6 100755
--- a/tests/devmem.test
+++ b/tests/devmem.test
@@ -9,14 +9,32 @@ testcmd 'read 2' '-f foo 0x8 2' '0x6568\n' '' ''
testcmd 'read 4' '-f foo 0x8 4' '0x6c6c6568\n' '' ''
testcmd 'read 8' '-f foo 0x8 8' '0x77202c6f6c6c6568\n' '' ''
+testcmd 'read --no-mmap default (4)' '--no-mmap -f foo 0x8' '0x6c6c6568\n' '' ''
+testcmd 'read --no-mmap 1' '--no-mmap -f foo 0x8 1' '0x68\n' '' ''
+testcmd 'read --no-mmap 2' '--no-mmap -f foo 0x8 2' '0x6568\n' '' ''
+testcmd 'read --no-mmap 4' '--no-mmap -f foo 0x8 4' '0x6c6c6568\n' '' ''
+testcmd 'read --no-mmap 8' '--no-mmap -f foo 0x8 8' '0x77202c6f6c6c6568\n' '' ''
+
head -c 32 /dev/zero > foo
NOSPACE=1 testcmd 'write 1' '-f foo 0x8 1 0x12 && od -t x foo' '0000000 00000000 00000000 00000012 00000000\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
NOSPACE=1 testcmd 'write 2' '-f foo 0x8 2 0x1234 && od -t x foo' '0000000 00000000 00000000 00001234 00000000\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
NOSPACE=1 testcmd 'write 4' '-f foo 0x8 4 0x12345678 && od -t x foo' '0000000 00000000 00000000 12345678 00000000\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
NOSPACE=1 testcmd 'write 8' '-f foo 0x8 8 0x12345678abcdef01 && od -t x foo' '0000000 00000000 00000000 abcdef01 12345678\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
+head -c 32 /dev/zero > foo
+NOSPACE=1 testcmd 'write --no-mmap 1' '--no-mmap -f foo 0x8 1 0x12 && od -t x foo' '0000000 00000000 00000000 00000012 00000000\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
+NOSPACE=1 testcmd 'write --no-mmap 2' '--no-mmap -f foo 0x8 2 0x1234 && od -t x foo' '0000000 00000000 00000000 00001234 00000000\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
+NOSPACE=1 testcmd 'write --no-mmap 4' '--no-mmap -f foo 0x8 4 0x12345678 && od -t x foo' '0000000 00000000 00000000 12345678 00000000\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
+NOSPACE=1 testcmd 'write --no-mmap 8' '--no-mmap -f foo 0x8 8 0x12345678abcdef01 && od -t x foo' '0000000 00000000 00000000 abcdef01 12345678\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
+
head -c 32 /dev/zero > foo
NOSPACE=1 testcmd 'write 1 multiple' '-f foo 0x8 1 0x12 0x34 && od -t x foo' '0000000 00000000 00000000 00003412 00000000\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
NOSPACE=1 testcmd 'write 2 multiple' '-f foo 0x8 2 0x1234 0x5678 && od -t x foo' '0000000 00000000 00000000 56781234 00000000\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
NOSPACE=1 testcmd 'write 4 multiple' '-f foo 0x8 4 0x12345678 0xabcdef01 && od -t x foo' '0000000 00000000 00000000 12345678 abcdef01\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
NOSPACE=1 testcmd 'write 8 multiple' '-f foo 0x8 8 0x12345678abcdef01 0x1122334455667788 && od -t x foo' '0000000 00000000 00000000 abcdef01 12345678\n0000020 55667788 11223344 00000000 00000000\n0000040\n' '' ''
+
+head -c 32 /dev/zero > foo
+NOSPACE=1 testcmd 'write --no-mmap 1 multiple' '--no-mmap -f foo 0x8 1 0x12 0x34 && od -t x foo' '0000000 00000000 00000000 00003412 00000000\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
+NOSPACE=1 testcmd 'write --no-mmap 2 multiple' '--no-mmap -f foo 0x8 2 0x1234 0x5678 && od -t x foo' '0000000 00000000 00000000 56781234 00000000\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
+NOSPACE=1 testcmd 'write --no-mmap 4 multiple' '--no-mmap -f foo 0x8 4 0x12345678 0xabcdef01 && od -t x foo' '0000000 00000000 00000000 12345678 abcdef01\n0000020 00000000 00000000 00000000 00000000\n0000040\n' '' ''
+NOSPACE=1 testcmd 'write --no-mmap 8 multiple' '--no-mmap -f foo 0x8 8 0x12345678abcdef01 0x1122334455667788 && od -t x foo' '0000000 00000000 00000000 abcdef01 12345678\n0000020 55667788 11223344 00000000 00000000\n0000040\n' '' ''
diff --git a/toys/other/devmem.c b/toys/other/devmem.c
index 9f9a9e03..e3727fd5 100644
--- a/toys/other/devmem.c
+++ b/toys/other/devmem.c
@@ -2,7 +2,7 @@
*
* Copyright 2019 The Android Open Source Project
-USE_DEVMEM(NEWTOY(devmem, "<1(no-sync)f:", TOYFLAG_USR|TOYFLAG_SBIN))
+USE_DEVMEM(NEWTOY(devmem, "<1(no-sync)(no-mmap)f:", TOYFLAG_USR|TOYFLAG_SBIN))
config DEVMEM
bool "devmem"
@@ -15,6 +15,7 @@ config DEVMEM
-f FILE File to operate on (default /dev/mem)
--no-sync Don't open the file with O_SYNC (for cached access)
+ --no-mmap Don't mmap the file
*/
#define FOR_devmem
@@ -62,32 +63,44 @@ void devmem_main(void)
flags = writing ? O_RDWR : O_RDONLY;
if (!FLAG(no_sync)) flags |= O_SYNC;
fd = xopen(TT.f ?: "/dev/mem", flags);
- map_off = addr & ~(page_size - 1ULL);
- 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);
+ if (FLAG(no_mmap)) xlseek(fd, addr, SEEK_SET);
+ else {
+ map_off = addr & ~(page_size - 1ULL);
+ map_len = addr + (writing ? (toys.optc - 2) * bytes : 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) {
for (int i = 2; i < toys.optc; i++) {
data = xatolu(toys.optargs[i], bytes);
- if (bytes==1) *(char *)p = data;
- else if (bytes==2) *(unsigned short *)p = data;
- else if (bytes==4) *(unsigned int *)p = data;
- else if (sizeof(long)==8 && bytes==8) *(unsigned long *)p = data;
- p += bytes;
+ if (FLAG(no_mmap)) xwrite(fd, &data, bytes);
+ else {
+ if (bytes==1) *(char *)p = data;
+ else if (bytes==2) *(unsigned short *)p = data;
+ else if (bytes==4) *(unsigned int *)p = data;
+ else if (sizeof(long)==8 && bytes==8) *(unsigned long *)p = data;
+ p += bytes;
+ }
}
} else {
- if (bytes==1) data = *(char *)p;
- else if (bytes==2) data = *(unsigned short *)p;
- else if (bytes==4) data = *(unsigned int *)p;
- else if (sizeof(long)==8 && bytes==8) data = *(unsigned long *)p;
+ if (FLAG(no_mmap)) xread(fd, &data, bytes);
+ else {
+ if (bytes==1) data = *(char *)p;
+ else if (bytes==2) data = *(unsigned short *)p;
+ else if (bytes==4) data = *(unsigned int *)p;
+ else if (sizeof(long)==8 && bytes==8) data = *(unsigned long *)p;
+ }
printf((!strchr(*toys.optargs, 'x')) ? "%0*ld\n" : "0x%0*lx\n",
bytes*2, data);
}
- if (CFG_TOYBOX_FORK) munmap(map, map_len);
+ if (CFG_TOYBOX_FORK) {
+ if (FLAG(no_mmap)) close(fd);
+ else munmap(map, map_len);
+ }
}
--
2.47.0.163.g1226f6d8fa-goog
More information about the Toybox
mailing list