我有一个带有用户空间驱动程序的PCIe设备.我正在通过BAR向设备写命令,命令对延迟敏感,数据量很小(~64字节),所以我不想使用DMA.
如果我在使用内核重新映射BAR的物理地址ioremap_wc,然后写64字节到BAR 的内核中,我可以看到,64字节PCIe上写成一个TLP.如果我允许我的用户空间程序到mmap带有MAP_SHARED标志的区域然后写入64字节,我会在PCIe总线上看到多个TPL,而不是单个事务.
根据内核PAT文档,我应该能够将写入组合页面导出到用户空间:
希望将某些页面导出到用户空间的驱动程序通过使用mmap接口和组合来完成
1)
pgprot_noncached()2)
io_remap_pfn_range()或remap_pfn_range()或vm_insert_pfn()通过PAT支持,
pgprot_writecombine添加了一个新的API .因此,驱动程序可以继续使用上述顺序,使用 步骤1pgprot_noncached()或pgprot_writecombine()步骤1,然后执行步骤2.
根据此文档,我的mmap处理程序中的相关内核代码如下所示:
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
return io_remap_pfn_range(vma,
vma->vm_start,
info->mem[vma->vm_pgoff].addr >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
Run Code Online (Sandbox Code Playgroud)
我的PCIe设备显示在lspci中,BAR标记为预期的预取:
Run Code Online (Sandbox Code Playgroud)Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 11 Region 0: Memory at d8000000 (64-bit, prefetchable) [size=32M] Region 2: Memory at d4000000 (64-bit, prefetchable) [size=64M]
当我mmap从用户空间调用时,我看到一条日志消息(设置了debugpat kernel …
我正在编写一个框架来实现在模拟器和未修改的主机软件中运行的RTL的协同仿真.编写主机软件以控制实际硬件,通常以两种方式之一工作:
前一种情况非常简单 - 编写一个库,它实现与驱动程序相同的读/写调用,并在运行模拟时与之相关联.这一切都非常有效,我可以运行未经修改的生产软件作为我的RTL模拟的刺激.
第二种情况比第一种情况要困难得多......
最初我以为我可以LD_PRELOAD用来拦截mmap调用.在我的实现中,mmap我会分配一些页面对齐的内存,然后mprotect设置一个信号处理程序来捕获SIGSEGV.
这种方法存在许多问题:
读取与写入
我可以确定访问的地址,siginfo_t->si_addr但不能确定访问是读还是写.
捕获重复访问
在信号处理程序中,我需要取消保护内存区域,否则SIGSEGV只要我的处理程序退出并且主机代码永远不会继续,我就会重复.但是,如果我取消保护区域,那么我的信号处理程序将不会捕获后续访问.
信号处理程序的肮脏
在模拟器驱动RTL并返回结果时阻塞信号处理程序违反了各种编程规则 - 特别是假设模拟器可以触发各种其他事件并在从此访问返回结果之前执行任意代码.
我想知道是否可以创建一个类似文件的对象,其行为类似于磁盘,而不是mprotect在缓冲区上使用.我没有找到任何表明这是可行的信息.
是否可以捕获对mmap区域的所有访问以及如何?
假设LD_PRELOAD并且mprotect是最佳路线:
mprotect该区域?我想包装各种对象的每个方法,除了__init__使用装饰器.
class MyObject(object):
def method(self):
print "method called on %s" % str(self)
@property
def result(self):
return "Some derived property"
def my_decorator(func):
def _wrapped(*args, **kwargs):
print "Calling decorated function %s" % func
return func(*args, **kwargs)
return _wrapped
class WrappedObject(object):
def __init__(self, cls):
for attr, item in cls.__dict__.items():
if attr != '__init__' and (callable(item) or isinstance(item, property)):
setattr(cls, attr, my_decorator(item))
self._cls = cls
def __call__(self, *args, **kwargs):
return self._cls(*args, **kwargs)
inst = WrappedObject(MyObject)()
Run Code Online (Sandbox Code Playgroud)
但是,包装属性实例结果等同于:
@my_decorator
@property
def result(self):
return "Some …Run Code Online (Sandbox Code Playgroud) c ×2
linux ×2
decorator ×1
linux-kernel ×1
metaclass ×1
mmap ×1
pci-e ×1
python ×1
system-calls ×1