pythonmmap

python mmap write with packed value


On Linux setup, I am trying to write device file using python's mmap.

Following is the code snippet:

import struct, os, mmap, sys

def write(addr, size, data):
        filename = "<pci_device_file>/resource0";

        # page size of this setup (typically 4k)
        psize = os.sysconf("SC_PAGE_SIZE")

        # mmap expects offsets to be multiple of page-size
        base_offset = int(addr // psize) * psize

        # offset within the page
        seek_sz = int(addr %  psize)

        # total bytes to be mapped = offset within the page + requested size
        map_size = seek_sz + size

        # open the dev file (of mem)
        fd = os.open(filename, os.O_RDWR|os.O_SYNC)

        # map the dev file to process address space
        mem = mmap.mmap(fd, map_size,
                mmap.MAP_SHARED,
                mmap.PROT_READ|mmap.PROT_WRITE,
                offset=base_offset)

        # goto the target offset (within the page that is mapped)
        mem.seek(seek_sz, os.SEEK_SET)
        val = mem.read(size)
        print ('Packed val read = {}'.format(val))
        print(hex(struct.unpack("I", val)[0]))

        # seek to same offset, now to write
        mem.seek(seek_sz, os.SEEK_SET)

        # pack the data
        packed_data = struct.pack("I", data)
        print('Packed val write = {}'.format(packed_data))

        # write to memory
        ret_code = mem.write(packed_data)

        # try to re-read the value written
        mem.seek(seek_sz, os.SEEK_SET)
        val = mem.read(size)
        print ('Packed val read (after write) = {}'.format(val))
        print(hex(struct.unpack("I", val)[0]))
        
        # close fd
        os.close(fd)

        return ret_code


write(0x4330, 4, int(sys.argv[1], 16))

When I run this code, I get the following output:

root@linux$ python3 /ssd/my_mmap.py 0x113d0000
Packed val read = b'\x00\x00="'
0x223d0000

Packed val write = b'\x00\x00=\x11'

Packed val read (after write) = b'\x00\x00="'
0x223d0000 ==> value not written

The address is writable and I could write it using C program. However, with python program, it was never able to write. Base-address, offset etc. values are correct - as I could read the old values using the same.

What am I missing? Sigh!


Solution

  • Wanted to update this for other's benefit.

    I guess, I was using the mmap wrongly. I needed to open the device file using built-in open instead of os.open. For some reason, that made a difference, though not sure why the latter did not work.

    As given in the link https://www.tutorialspoint.com/memory-mapped-file-support-in-python-mmap , after I modified the code to use built-in open I was able to write the contents (both in pci device file and the regular file).

    import mmap
    
    def mmap_io_write(fname):
       with open(fname, mode="r+") as fobj:
          with mmap.mmap(fobj.fileno(), length=0, access=mmap.ACCESS_WRITE) as mmap_obj:
             mmap_obj[20:26] = b"Hello!"
             mmap_obj.flush()