[Toybox] [PATCH] Support non memory mapped access
Karthik Ramasubramanian
kramasub at google.com
Fri Oct 25 13:14:18 PDT 2024
On Fri, Oct 25, 2024 at 10:06 AM Rob Landley <rob at landley.net> wrote:
> On 10/24/24 09:45, enh wrote:
> > On Wed, Oct 23, 2024 at 7:02 PM Karthikeyan Ramasubramanian <
> > kramasub at google.com> wrote:
> >
> >> 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.
> >>
> >> ---
> >> android/device/generated/flags.h | 8 +++--
> >> android/device/generated/help.h | 2 +-
> >> android/device/generated/newtoys.h | 2 +-
> >> android/linux/generated/flags.h | 8 +++--
> >> android/linux/generated/help.h | 2 +-
> >> android/linux/generated/newtoys.h | 2 +-
> >> android/mac/generated/flags.h | 8 +++--
> >> android/mac/generated/help.h | 2 +-
> >> android/mac/generated/newtoys.h | 2 +-
> >>
> >
> > (these files only exist in AOSP ... sorry, i should have said to apply
> your
> > devmem.c change to a fresh `git clone` of upstream!)
>
> I already stripped the android files off and applied it locally
> yesterday, although that was mostly so I could go:
>
> git diff -b HEAD^1 HEAD
>
Sorry that I added android files. I will remove them in the next patch
revision.
>
> I left off yesterday looking at:
>
> - map_len = (addr+bytes-map_off);
> + map_len = addr + (writing ? (toys.optc - 2) * bytes : bytes) -
> map_off;
>
> Which presumably corresponds to the commit comment section:
>
> Also currently only WIDTH bytes are mapped into memory even when
> more data is accessed. Fix this by mapping WIDTH * number of data.
>
> And I'm going... that's unrelated to the rest of the patch and seems
> like a user interface change? If nobody noticed this before now, what's
> going on here?
>
> Looking at it today, I _think_ the issue is that mmap() gets rounded up
> to page size and if you either do a lot of data at a size larger than
> bytes, or do an unaligned access that goes off the edge of the page,
> this could go boing?
>
> >> // 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);
> >> + xlseek(fd, bytes, SEEK_CUR);
> >
> > is this clearer if you remove the xlseek at the top, and move this
> xlseek()
> > before the xwrite()? i know that would mean incrementing addr, but at
> least
> > the reasoning is localized (and you don't have (a) "aren't these the
> wrong
> > way round?" and (b) "do we actually need a SEEK_CUR? why didn't the write
> > advance the file offset?").
>
> It's a pity there aren't any tests using "-f filename" to modify a local
> file created and checked with xxd.
>
> (Also, xxd is not in the debian base install but the test suite is now
> full of uses of it, meaning "TEST_HOST=1 make tests" doesn't pass in a
> fresh debootstrap. Sigh, gotta document dependencies. New FAQ entry on
> setting up a testing debootstrap I guess...)
>
> My problem here is I dunno what the expected use case is: do you
> normally read lots of things in sequence in a single invocation, or or
> scattered around? My mental model before this was you run the command
> once per read/write pair and stick a shell for loop around it if you
> wanted anything fancier, neither of which would require a loop or more
> than one lseek(), but apparently not...
>
The sequential use-case is:
devmem -f ${path_to_file} ADDR WIDTH DATA1 DATA2 .. DATAn
where each DATA is of size WIDTH bytes. Also this sequential use-case is
currently supported only for write access. The sequential read access
use-case
is currently not supported in devmem. This sequential use-case supports
writing to WIDTH * n contiguous bytes in a file/device.
>
> usage: devmem [-f FILE] ADDR [WIDTH [DATA...]]
>
> Read/write physical addresses. WIDTH is 1,2,4, or 8 bytes (default 4)
> Prefix ADDR with 0x for hexadecimal, output in same base as address.
>
> How would one specify two disjunct read/write addresses? There's no
> square bracket around "ADDR". And how would you specify multiple widths?
Multiple widths or addresses cannot be specified in a single invocation.
For that,
one has to invoke each address and width scenario separately.
>
> It just seems like you specify one address, and then MAYBE specify one
> width, and then specify data. And if you don't specify anything (since
> everything in square brackets is presumably optional" it does SOMETHING,
> presumably read and display one 4 byte value at the address?
Yes, that is correct.
>
> Why would you ever need a seek after the write then? Didn't it advance
> to the right place naturally?
>
That is again my bad. I confirmed that with this extra xlseek, it advanced
to
unexpected offset and accessed incorrect bytes. I will fix this in the next
patch revision. I will also update the test case to test this scenario as
well.
>
> Rob
>
Thanks and Regards,
Karthikeyan.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.landley.net/pipermail/toybox-landley.net/attachments/20241025/76257889/attachment-0001.htm>
More information about the Toybox
mailing list