python mmap skipping every second byte when writing -
i have strange problem using mmap in python when writing memory (/dev/mem). clear, reading done in same manner , works ok. when comes writing, seems every second byte unwritable.
ex.
when read addr 0x200 val 0x1234 when try write addr 0x200 val 0x4321 written addr 0x200 val 0x0021
when try write byte byte, same happens. ex.
write: addr 0x200 0x43 addr 0x201 0x21 addr 0x200 0x00 addr 0x201 0x21
code:
class pydump: def __init__(self, addr, length = 1, word_size = 4, filename = '/dev/mem'): if addr < 0 or length < 0: raise valueerror('address or length invalid') self._verbose = verbose self.word_size = word_size self.mask = ~(self.word_size - 1) self.base_addr = addr & ~(mmap.pagesize - 1) self.addr_offset = addr - self.base_addr self.word_length = length self.no_of_bytes = self.word_length * self.word_size # align length full words end_addr = addr + self.no_of_bytes if end_addr % self.mask: end_addr = (end_addr + self.word_size) & self.mask self.map_length = end_addr - self.base_addr self.fname = filename self.fd = os.open(self.fname, os.o_rdwr | os.o_sync) self.mem = mmap.mmap(self.fd, self.map_length, mmap.map_shared, mmap.prot_read | mmap.prot_write, offset=self.base_addr) def read(self): mem = self.mem virt_base_addr = self.addr_offset & self.mask mem.seek(virt_base_addr) data = [] in range(self.no_of_bytes): data.append(struct.unpack('b', mem.read_byte())[0]) abs_addr = self.base_addr + virt_base_addr return pydumpbuffer(abs_addr, data, self.word_size) def write(self, data): mem = self.mem virt_base_addr = self.addr_offset & self.mask mem.seek(virt_base_addr) if self.word_size == 1: mem.write(struct.pack('b', data)) elif self.word_size == 2: mem.write(struct.pack('h', data)) elif self.word_size == 4: mem.write(struct.pack('i', data)) else: raise valueerror('invalid word size') def write_bytes(self, bytes): if len(bytes) != self.no_of_bytes: raise valueerror('wrong number of bytes given') mem = self.mem virt_base_addr = self.addr_offset & self.mask mem.seek(virt_base_addr) byte in bytes: mem.write_byte(byte)
example run (i prepared memory other memdump tool [bin] 0xeeeeeeee):
>>> pydump import pydump memdump >>> memdump(0x18007c20, 1, 4).read() 0xeeeeeeee >>> memdump(0x18007c20, 1, 4).write(0x12345678) >>> memdump(0x18007c20, 1, 4).read() 0x00340078 >>> memdump(0x18007c20, 1, 4).write(0x87654321) >>> memdump(0x18007c20, 1, 4).read() 0x00650021
example no 2 (i not write 2 bytes @ 'first' byte place):
>>> memdump(0x18007c20, 1, 2).write(0xabcd) >>> memdump(0x18007c20, 1, 4).read() 0x00650021 >>> memdump(0x18007c21, 1, 1).write(0xcd) >>> memdump(0x18007c20, 1, 4).read() 0x00650021 >>> memdump(0x18007c22, 1, 1).write(0xcd) >>> memdump(0x18007c20, 1, 4).read() 0x00cdcd00
any thoughts on problem ?
i know wrong now. answer it's fault of python specific hardware/driver.
i looked through implementation of mmap , uses memcpy, know copies byte byte. in c implemention did not happen, when needed write 4 bytes, 4 bytes written. here comes limitation of hardware/driver every register must written in full (i did not know @ time of stating question), when writing byte byte weird behaviour.
some registers 16bit , 32bit. when writing 0xffff 16bit register ended having 0x00ff. memcpy copying 0xff twice. driver got write(0xff) write(0xff), doing (because of python) 2 writes register of byte 0xff :) same happened 32bit registers, although looked different (but driver may behave different).
for work have change implementation of python mmap :(
Comments
Post a Comment