2016-09-18 2 views
1

Я хочу получить доступ к памяти пользователя с платы PCIe, которая обеспечивает 1 ГБ памяти с помощью BAR0. В настоящее время я использую только функции чтения и записи моего драйвера устройства символов, который ОЧЕНЬ медленный (чтение 1 МБ/с и запись 16 МБ/с) на 8-разрядном PCIe Gen3.Возможно ли использовать MMAP для памяти PCI BAR?

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 - единственный вариант?

Заранее благодарен!

/Jesko

ответ

0

я узнал, как это работает:

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

Смежные вопросы