是否可以对 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
我想用户从提供 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