是否可以对 PCI BAR 内存进行 MMAP?

Is it possible to MMAP a PCI BAR memory?

我想用户从提供 1GB 内存和 BAR0 的 PCIe 板访问内存。 目前我只使用我的字符设备驱动程序的读写功能,这在 8x PCIe Gen3 上非常慢(1MB/s 读取和 16MB/s 写入)。

static ssize_t
MPD_read(
    struct file *filp,
    char *buffer,
    size_t bufferSize,
    loff_t *offset )
{
    unsigned long unusedBytes = copy_to_user(
        ( void * ) buffer,
        MPD_AdapterBoard.bars[ 0 ].barHWAddress,
        bufferSize );
    return 0;
}

static ssize_t
MPD_write(
    struct file *filp,
    const char *buffer,
    size_t bufferSize,
    loff_t *offset )
{
    unsigned long unusedBytes = copy_from_user(
        MPD_AdapterBoard.bars[ 0 ].barHWAddress,
        ( void * ) buffer,
        bufferSize );
    return 0;
}

是否可以使用 MMAP(通过 .mmap 文件操作)来获得更快的速度? 还是 DMA 是唯一的选择?

提前致谢!

/杰斯科

我发现它是如何工作的:

static int
    MPD_mmap(
    struct file *filp,
    struct vm_area_struct *vma )
{
    unsigned long offset;

    offset = vma->vm_pgoff << PAGE_SHIFT;
    if (( offset + ( vma->vm_end - vma->vm_start )) > MPD_AdapterBoard.bars[ 0 ].barSizeInBytes )
    {
        return -EINVAL;
    }

    offset += ( unsigned long ) MPD_AdapterBoard.bars[ 0 ].mmioStart;

    vma->vm_page_prot = pgprot_noncached( vma->vm_page_prot );

    if ( io_remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot ))
    {
        return -EAGAIN;
    }
    return 0;
}

注意:这是一项正在进行的工作,因此错误检查相当有限。

希望对这里的人有所帮助,可以从这里下载包括测试程序在内的完整代码:https://github.com/jesko42/minipci