在Linux设置中,我尝试使用python的
mmap
编写设备文件。
以下是代码片段:
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))
当我运行此代码时,我得到以下输出:
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
地址是可写的,我可以用C程序来写。 然而,用python程序,却始终无法编写。 基地址、偏移量等值是正确的 - 因为我可以使用相同的值读取旧值。
我错过了什么?叹息!
想更新此内容以造福他人。
我想,我错误地使用了
mmap
。
我需要使用内置的 open
而不是 os.open
打开设备文件。
出于某种原因,这产生了影响,尽管不确定为什么后者不起作用。
如链接中给出的https://www.tutorialspoint.com/memory-mapped-file-support-in-python-mmap,在我修改代码以使用内置
open
后,我能够编写内容(pci 设备文件和常规文件中)。
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()