LINUX.ORG.RU

написать драйвер для своего устройства

 ,


6

13

Есть некое устройство (на базе ПЛИС), которое видится в системе через lspci, оно сконфигурировано, назначены адресные пространства и т.д. Осилена книга «PCI Express Technology. Comprehensive Guide to Generations 1.x, 2.x, 3.0», принципы работы PCI Express стали полностью понятны.

Теперь нужно с этим устройством работать. Для этого требуется свой драйвер для ОС Linux. Есть крохи информации в LDD3 (почти бесполезные), есть такой пример http://www.fpga4fun.com/PCI6.html

Подскажите какой-нибудь простейший пример PCI драйвера (самый маленький в ядре), или может есть руководство или книжка на эту тему.

Требуется: самый наипростейший интерфейс, чтобы устройство виделось как файл и его можно было бинарно считывать (с большой скоростью, разумеется).

Для начала (самый простой вариант) - на устройстве допустим на всем диапазоне запрошенного и выделенного ему адресного пространства лежит повторяющийся одинаковый текст (из пары слов), просто нужно в программе через драйвер этот текст считать с максимальной скоростью (DMA) и вернуться к исполнению программы.

Ответ на: комментарий от anonymous

Ух ты! Люто спасибирую анонимуса!

А тут интересная дока нашлась: http://blog.idv-tech.com/wp-content/uploads/2014/09/drivers-session3-uio-4pub... где расписывают плюсы такого подхода!

Конечно, это лишь на первое время, для начала и такой дров сойдет, а потом когда потребуется привязка с какой-то подсистеме - придется изучать что-то сложнее...

I-Love-Microsoft ★★★★★
() автор топика

Почитал свою же ссылку - похоже у UIO драйвера много ограничений, это не серьезный подход, разве что первые шаги по отладке.

Так что ответы еще принимаются, всё же надо что-то более полноценное.

I-Love-Microsoft ★★★★★
() автор топика

А что, разве в LDD не описано, как писать драйвер для PCI-устройств? Для доступа из user space можно оформить все это хозяйство как char-устройство, к примеру.

zloy_starper ★★★
()

А вариант сделать мост на usb3 (для большой скорости) через ftdi или cypress рассматривался? Ведь подключить эти не очень дорогие чипы, наверняка, довольно просто. С программной точки зрения, по-моему, это простые FIFO. Да ещё и гибко в плане подключения ПЛИС к ПК.

gag ★★★★★
()
Ответ на: комментарий от gag

Суть не просто связать устройство с ПК (и не только ПК!) максимально простым способом (а таких куча, в том числе и через USB3 тех же FTDI и др.), а разработать именно полноценное PCI устройство.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Ну, если принципиально, то тоже можно. Несколько лет назад натыкался. Сейчас погуглил: israel fpga pcie driver. И первая ссылка - оно: http://xillybus.com и прямая ссылка на исходники драйвера. И, как я уже намекал, оно там в виде FIFO. Кстати, они также IP предлагают.

gag ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

а разработать именно полноценное PCI устройство

занимались мы такой работой в одной компании. причём много лет. в среднем, на разработку, отладку и выкатку в продакшен одной серьёзной PCIe платы уходило не меньше года. это если специалисты опытные, заранее знают всё о шине и уже имеют опыт разработки, разводки и т.д. и если все схемы с заказом печати и пайки отлажены.

там проблемы не столько в протоколе, сколько в реальной работе с разными мамками. вот когда настоящий зоопарк появляется! потому что стандарты стандартами, а в реальной жизни это нифига не так. и у каждой мамки свои косяки. мелкие, но часто достаточные для того, чтобы долго колупаться с осциллом (а там ещё и осцилл нужен недешёвый, кстати), чтобы понять, почему оно не работает.

с готовыми мостами тоже не намного меньше возни. тысячи страниц документации, иногда не очень понятные (или даже неправильные!) схемы обвязки (если производитель вообще этим заморачивается). так что там куда ни плюнь - везде какая-нить засада.

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 2)
Ответ на: комментарий от Iron_Bug

Тем не менее, первая попавшая мне мамка - мой старый комп с двумя PCIe x16 разъемами - прекрасно видит мою платку, настраивает ее как надо (хотя для обмена данных еще предстоит драйвер, но именно сам процесс настройки делает корка). После прочтения книги, мне начинает казаться что PCI - прост как тапок, особенно по части настройки именно endpoint-а.

У меня платка от Lattice (хотя есть же и Altera и Xilinx), так вот у Lattice корка PCIe чисто «софтовая» поверх их примитивного (в плане - базового) PCS/SERDES, а весь PCIe чисто поверх этого фундаментального блока, т.е. там нет аппаратных блоков именно для PCIe, этот интерфейс там чисто электрически совместим. Так вот они пишут о 100% прохождения тестов интероперабельности в PCI-SIG их коркой.

Я такой еж, что меня голой не напугаешь :)

К тому же альтеровская платка с PCIe тоже увиделась настроилась определилась - тоже с пол пинка.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Если не секрет, что вы в Vendor ID писали?

1234 :) мы делали очень специфические девайсы для своих машин (банковское оборудование), они отдельно от этих машин нигде не применялись. когда начинали всё это дело - было ваще пофигу. а потом регистрацию этого ID всё откладывали. так и жило там написанное когда-то 1234. я не знаю, сейчас они зарегистрировали их или нет (фирма существует и продолжает разработку). при том, что всякие там гостовские номера у нас были выделены под техническую документацию и прочие бумажки и сертификаты типа ISO имелись. но в целом эти идентификаторы нужны только если собираешься заниматься ширпотребом и продавать карты напрямую потребителям.

Iron_Bug ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

мы сначала делали ваще ISA платы. потом PCI. потом купили мост PCI-PCIe и начали «по-быстрому» переводить платы на PCIе, потому что PCI чипы к тому времени вообще уже снимали с производства. но PCIe тогда только начинался. возможно, он был ещё довольно сырой. но по-быстрому у нас не получилось. поимели много тараканов с синхронизацией сигналов на шине. причём с некоторыми мамками всё работало искаропки, а с некоторыми возникали таинственные глюки. иногда оказывалось, что мамки не совсем точно соблюдают стандарты и кое-где тайминги выше, чем допустимо, например. вплоть до тупых несоответствий по размеру слота (да, и такое бывало) или хреновых контактов в этих слотах. а нам надо было обмен скоростной организовать через DMA, это был захват изображений, очень большой поток данных и его ещё надо было ещё всяко нарезать на лету, чтобы скармливать программистам уже более-менее готовенькое. в итоге мы года полтора корячились и таки заставили это всё работать. но гемора было много и документации пришлось перелопатить просто тыщи страниц.
потом ещё долго искали, кто нам напечатает платы. в итоге, печатали их в Тайване и BGA запаивали там же. зато тайцы сделали всё как полагается. ни одной(!) бракованной платы из партии в несколько тыщ штук. при том, что BGA-шек там было много, платы восьмислойные и шаг местами был до 0.1. и они нигде не накосячили с металлизацией и пропаем BGA-шек. в сравнении с нашими, где отсев по браку иногда составлял до 40% плат, это было просто небо и земля.

с шиной был один забавный глюк. пропадали пакеты. искали везде, где угодно, кроме электроники. оказалось - впаяли не совсем правильный номинал резистора уже на выходе на шину. в итоге этого хватило, чтобы первый сигнал просаживался и весь пакет игнорировался. вот так рядовой резистор может сожрать пакет :) а его там фиг разглядишь, настолько он, сцуко, мелкий. а мы-то искали в протоколе, в обмене данными. пока разобрались - весь мозг себе вынесли.

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 2)
Ответ на: комментарий от Harald

например какие?

тайминги, не соответствующие стандартам. совсееем маленько. но не соответствующие. или даже размеры слота. китайцы умудрялись делать слоты, в которые плата без доработки напильником просто не влезала, хотя мы измеряли - у нас было всё по стандарту. бывало, что с DMA какие-то косяки - тоже тайминги, клоки, сигналы, локи на шине. мелочи, которые не дают плате нормально работать.

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)
Ответ на: комментарий от Iron_Bug

а как тогда вообще материнки с рандомными ширпотребными девайсами работают? :) Их же должны как-то тестировать на производстве, втыканием какой-нибудь эталонной PCIe карты хотя бы

Harald ★★★★★
()
Ответ на: комментарий от Harald

+1, если бы в общем случае всё было так - тогда бы ничего в мире не работало.

На самом низком физическом уровне PCIe прост как тапок, достаточно соблюдать несложные правила, к тому же стабильность клока допустима до 300 ppm если не ошибаюсь, что весьма комфортно. Да и пакеты тоже стандартизированы.

Яркий пример - Ethernet, не будь правила просты и однозначны, я бы это уже давно заметил на своей практике.

Ладно, спасибо Iron_Bug за предупреждение, буду иметь ввиду что могут быть проблемы.

Но главная тема: написать драйвер. Пока исходим из того что у меня есть - железо определилось, обменялось конфигурационными пакетами, считаем что линк рабочий и всё. Железные проблемы пока выносим за скобки - их нет, в слот лезет, питание поступает.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от Harald

ширпотребу не нужны скорости и нагрузки. а для сложных плат производитель явно пишет: вот с этим железом мы тестировали и гарантируем. а с другим - нет. так бывает с мамками и памятью, например. чем выше скорость обмена - тем больше там ограничений, как правило.

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)
Ответ на: комментарий от Iron_Bug

Топовым видеокартам не нужны скорости и нагрузки? Ладно, не суть.

Раз ваша фирма создавала устройства, то по каким учебным материалам сотрудники учились писать драйвер для скоростей?

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

топовые не есть высоконагруженные. высоконагруженные - это какие-нить стримеры с видеокамер, например. или скоростные камеры. вот это высоконагруженные. а юзерская требуха - это так, фигня. для PCIe это не нагрузка. например, у нас девайс загребал, пережёвывал и выплёвывал в DMA около 200 метров данных в секунду. никакому юзерскому «топовому» харду такое даже близко не нужно.

Iron_Bug ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Раз ваша фирма создавала устройства, то по каким учебным материалам сотрудники учились писать драйвер для скоростей?

этим сотрудником была я, собсна. всё это из опыта и из кучи информации в сети. никаких учебников по этому делу нет, во всяком случае, я таковых не видела. тупо сидишь и читаешь документацию на чипы. и со стороны харда был один разработчик, он тоже сам учился, в основном. как это всё срастить вместе - мы сообща думали. совместно читали доки на мост, пробовали разные параметры, сидели часами с осциллом, писали и гоняли разные тесты на скорость, задавали вопросы производителям чипов. я со своей стороны, он со своей. так вдвоём всё и пилили. такая плата не сразу проектируется. сначала был сделан тестовый прототип, а до него была работа с тулкитом с мостом, чтобы вообще выяснить, а подходит ли нам этот чип.

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)
Ответ на: комментарий от Deathstalker

кстати, правильно замечено, что под Linux писать дрова гораздо проще. мне приходилось писать и под маздай, причём даже ещё под 98-й. под Linux-ом хоть отлаживать это всё по-человечески можно, это вообще праздник по сравнению с офтопиком.

Iron_Bug ★★★★★
()
Ответ на: комментарий от Iron_Bug

Отлично, я тогда можно вопросы буду задавать? Ну, когда возникнут. Я пока только собираюсь с мыслями по теме... У меня пока только пример от производителя заработал, а я хочу попробовать свою корку сгенерить - судя по докам, обмен служебными TLP-пакетами она осуществляет сама и «увидится» системой сразу.

Сам же юзер-интерфейс там таков, что надо генерить TLP пакеты самому, хотя без CRC, заголовки соображать и т.д., это чуть сложнее чем у тех же Xilinx, но так даже интереснее.

Наверное пару недель у меня займет подготовка. А потом хочется сделать так, чтобы драйвер запрашивал один маленький простой пакет, а я в ответ бы пытался что-то выслать.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

ты только вопросы конкретизируй. а то сферический девайс в вакууме без требований - это малопонятно. начни ковырять, тогда появятся уже конкретные вопросы.
я в последние годы конкретно PCI не занималась. если хочешь прямо свежие примеры - смотри дрова в актуальном для твоих нужд кернеле. но для начала разберись, что там за чип и как им управлять.

Iron_Bug ★★★★★
()

Есть крохи информации в LDD3

O_o А я учился еще по LDD2.

Чего не хватает в профильной главе LDD3?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Я потом скажу, вероятно обработка прерываний и работа через mmap описана в других разделах, может поэтому мне, нубу, эта инфа показалась отрывочной, надо читать с нуля походу всю книгу...

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

работа через mmap

Описание работы через mmap в LDD3 устарело, да. Но тебе mmap вначале тупо не нужен - сделай через read/write, это и проще, и концептуальнее.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Iron_Bug В общем, сделал устройство со своими ID (AAAA/BBBB), один регион памяти 4 килобайта:

Region 0: Memory at fe9ff000 (32-bit, non-prefetchable) [size=4K]
Всё успешно определяется, показывает мой модуль в поле «Kernel driver in use:». У самого устройства есть счетчик принятых пакетов (выводится на гребенку светодиодов), периодически ловит пакеты для соседних устройств, но корка проверяет диапазоны адресов и если он попадает в BAR0 - есть возможность увидеть это.

А теперь конкретный вопрос: где смотреть результаты pci_request_regions? В lspci видно что в данный конкретный момент моему устройству выделена память начиная с fe9ff000 и так до fe9fffff, т.е. 4К. Где увидеть этот адрес в драйвере, через какие структуры? Как осуществить запись N байт начиная с fe9ff000? Но для начала этот адрес еще узнать надо...

#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
//MODULE_LICENSE("GPL");

#define VENDOR_ID 0xAAAA
#define DEVICE_ID 0xBBBB

static struct pci_device_id mypci_id[] =
{
    { VENDOR_ID, DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
    {}
};

int device_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
    int ret;
    ret = pci_enable_device(dev);
    if(ret < 0)
    {
        printk(KERN_WARNING "mypci: unable to initialize PCI device\n");
        return ret;
    }

    ret = pci_request_regions(dev, "mypci");
    if(ret < 0)
    {
        printk(KERN_WARNING "mypci: unable to reserve PCI resources\n");
        pci_disable_device(dev);
        return ret;
    }

    printk(KERN_INFO "mypci: device_probe successful\n");
    return ret;
}

void device_remove(struct pci_dev *dev)
{
    pci_release_regions(dev);
    pci_disable_device(dev);
    printk(KERN_INFO "mypci: device removed\n");
}

struct pci_driver mypci =
{
    name: "mypci",
    id_table: mypci_id,
    probe: device_probe,
    remove: device_remove
};

static int __init init_module_mypci(void)
{
    printk(KERN_INFO "mypci: init\n");
    return pci_register_driver(&mypci);
}

static void __exit cleanup_module_mypci(void)
{
    printk(KERN_INFO "mypci: cleanup\n");
    pci_unregister_driver(&mypci);
}

module_init(init_module_mypci);
module_exit(cleanup_module_mypci);
I-Love-Microsoft ★★★★★
() автор топика
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от I-Love-Microsoft

Обычно после pci_request_regions() (или аналогичного request_mem_region()) вызывается ioremap_nocache() или аналоги, после чего можно читать и писать в регистры PCI-устройства через ядерные процедуры {read,write}{b,w,l} и т. п. Обычно делаются макросы типа

#define drivername_readl(reg) readl(dev->mmio + reg)
#define drivername_writel(reg, value) writel((value), dev->mmio + reg)

Пример: https://github.com/bluecherrydvr/linux/blob/tw5864/drivers/media/pci/tw5864/t... (хотел бы дать пример из основного репозитория ядра, но пример из своего драйвера, которого ещё там нет, кажется более простым для понимания).

Andrey_Utkin ★★
()
Ответ на: комментарий от I-Love-Microsoft

Память мапится примерно так:

p = ioremap_nocache(pci_resource_start(pdev, 0), 
                    pci_resource_len(pdev, 0));

Макросы, упомянутые в предыдущем посте, нужно делать типобезопасными inline-функциями:

static inline u32 mmio32_read(u32 *reg) { return readl(reg); }

static inline void mmio32_write(u32 *reg, u32 val) { writel(val, reg); }
tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

pci_resource_start(pdev, 0)

Тут 0 - это BAR0? А для BAR3 соответственно (pdev, 3)?

Про макросы понял. Мне конечно рано еще об этом (надо еще парсинг TLP пакетов в ПЛИСине накукарекать, а потом еще формирование для отправки - тоже не просто), но как считать сразу весь блок 4К при помощи механизма DMA? Чтоб не в каждый адрес тыкаться, а сразу слизать прям все 4К?

В дальнейшем я конечно сделаю гораздо больший регион памяти, и буду считывать поочередно разные участки (типа swap buffers)...

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

как считать сразу весь блок 4К при помощи механизма DMA

Насколько я понимаю DMA, тебе нужно дать команду своему PCI-устройству о том, чтобы устройство записало 4К в заданный физический адрес в оперативке. Саму команду опять же обычно отправляют через запись в какой-то регистр.

Как ПЛИСине скомандовать сделать запись 4к через PCI-DMA - другой вопрос, тут ничего не могу подсказать.

Andrey_Utkin ★★
()
Ответ на: комментарий от Andrey_Utkin

Дело в том что на стороне ПЛИС само понятие DMA в моем случае бессмысленно, я там просто получаю ряд пакетов, в которых есть команда записать N байт начиная с некоторого адреса, может я их вообще в FIFO запихивать буду, не важно.

А вот как на стороне драйвера ОС Linux инициировать процесс записи (например 1 мегабайта) без участия процессора? Этакое memcpy где я просто откуда куда и сколько байт.

Равно как и чтение, чтобы прочитать сразу N байт начиная с определенного адреса (а этот адрес как раз начало того что записано у меня в BAR0).

I-Love-Microsoft ★★★★★
() автор топика
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от I-Love-Microsoft

pci_resource_start(pdev, 0)

Тут 0 - это BAR0?

Да. Глава 12 LDD 3, кстати.

как считать сразу весь блок 4К

Для этого придется, внезапно, делать поддержку DMA в твоем устройстве. Без этого только MMIO.

само понятие DMA в моем случае бессмысленно, я там просто получаю ряд пакетов, в которых есть команда записать N байт начиная с некоторого адреса

Понятие DMA никогда не бессмысленно. В твоем случае нужно как минимум сообщить устройству, куда писать данные и каким прерыванием извещать процессор об окончании транзакции, а от этого уже недалеко и до нормальных DMA-дескрипторов и scatter-gather.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 2)
Ответ на: комментарий от I-Love-Microsoft

Как подтверждает моё мнение и tailgunner, DMA-чтение это по сути запись в RAM со стороны PCI-устройства. Тебе нужно через PCI-протокол производить это на стороне периферийного устройства.

Andrey_Utkin ★★
()
Ответ на: комментарий от I-Love-Microsoft

прочитать сразу N байт начиная с определенного адреса (а этот адрес как раз начало того что записано у меня в BAR0)

Довольно подозрительная фраза. Я хоть и не железячник, но мне кажется, что в BARn вообще не адреса RAM. Прошивке просто нечего оттуда читать.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Для этого придется, внезапно, делать поддержку DMA в твоем устройстве. Без этого только MMIO.

MMIO это значит каждый байт/word/dword будет записываться под контролем CPU?

Если я выделил в BAR3 диапазон 16 мегабайт, разве нет пути заставить компьютер осуществить непрерывную запись по этому диапазону N байт без участия CPU?

А чтение например 8 мегабайт начиная с определенного адреса разве невозможно без участия CPU не реализуя ничего особенного на стороне ПЛИС? Может я буду выгружать что-то из FIFO и отправлять с каждым пакетом чтения всё новые данные из FIFO.

Прошу прощения за глупые вопросы, просто я надеялся что раз у меня есть диапазон адресов, то компьютер может работать с ним как с куском памяти и читать его без CPU, а на стороне ПЛИС это будет просто ряд TLP MrD запросов по определенным адресам...

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Я с азами PCI-протокола не знаком, но у меня сложилось впечатление, что команды чтения-записи «из/на» PCI-устройста обрабатываются периферией именно как _команды_ (RPC, если хотите), а не как доступ к ячейкам памяти.

Andrey_Utkin ★★
()
Ответ на: комментарий от I-Love-Microsoft

Если я выделил в BAR3 диапазон

Память не выделена, а «замаплена». То есть ядро, при обращении на этот диапазон адресов с помощью заданного набора функций, производит команды чтения/записи для PCI-устройства, по соответствующим смещениям.

Andrey_Utkin ★★
()
Ответ на: комментарий от tailgunner

Andrey_Utkin

Довольно подозрительная фраза. Я хоть и не железячник, но мне кажется, что в BARn вообще не адреса RAM. Прошивке просто нечего оттуда читать.

Поправьте если ошибаюсь:

Насколько я понял, при включении компьютера, BIOS довольно простым способом опрашивает устройства с целью выяснить сколько диапазонов и каких размеров хотят устройства. Так, выяснив что устройство хочет диапазон 4K - выделяет его в общем адресном пространстве и это значение адреса попадает например в BAR0, причем адреса соседних устройств оказываются рядом, как на шашлыке нанизываются диапазон за диапазоном (в lspci это видно).

Всё общение происходит пакетами MRd->CplD (чтение - в ответ пакет с данными что лежат по этому адресу) и MWr (запись по адресу, без ответа). Если компьютер хочет записать мегабайт в устройство, то он, например начиная с адреса в BAR0, записывает этот мегабайт. Это выливается в N пакетов MWr (в зависимости от max payload к пакетам), в каждом пакете свое значение начального адреса + данные, и адрес инкрементируется. Чтение по адресу - это тоже N пакетов MRd.

Я почему засомневался... Вижу примеры для ПЛИСины по части PCI-E+SG-DMA, но там есть и другой пример, который чисто на проверку пропускной способности... и там PCI-E БЕЗ DMA на стороне ПЛИС. Там чисто чтение и запись по инициативе хоста (драйвера).

Именно так я и хочу поступить. Хочу чтобы когда нужные данные накопятся (например, если это изображение, то несколько строк) - я формирую прерывание (Message Signaled Interrupt, корка поддерживает) из ПЛИС и драйвер считывает новые данные САМ. А когда надо - записывает, т.е. всё будет по инициативе хоста.

Поэтому хочется понять как инициировать такие протяженные действия (запись большого числа байт) из драйвера Linux.

I-Love-Microsoft ★★★★★
() автор топика
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от Andrey_Utkin

Память не выделена, а «замаплена». То есть ядро, при обращении на этот диапазон адресов с помощью заданного набора функций, производит команды чтения/записи для PCI-устройства, по соответствующим смещениям.

Это понятно.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Похоже, вы не понимаете цимес DMA. Ещё раз - что для хоста DMA-чтение, то для периферии - DMA-запись.

драйвер считывает новые данные САМ

Тогда это уже не DMA, если код ядра что-то делает для считывания данных.

Чтобы вы могли разом получить доступ к целому буферу данных после прерывания, до этого прерывания периферия должна писать данные прямиком в хостовый RAM, используя регион физической памяти, предварительно полученный вызовом dma_alloc_coherent(). Адрес, записанный этой функцией по указателю из третьего аргумента, нужно после этого сообщить периферийному устройству.

Andrey_Utkin ★★
()
Ответ на: комментарий от I-Love-Microsoft

другой пример, который чисто на проверку пропускной способности... и там PCI-E БЕЗ DMA на стороне ПЛИС. Там чисто чтение и запись по инициативе хоста (драйвера)

Уточню что это пример на проверку пропускной способности выдает пиковый теоретический максимум, это значит что на стороне процессора явно не по несколько байт за раз пишется-читается. В то же время в блок-схеме этого примера явно отсутствует какой-либо DMA и даже упоминание о нем.

Вот мне так надо :) Жаль там дрова лишь для оффтопика, мне бы такое же в Linux...

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

Кури bus master для PCI target'а. Это надо впилить в ПЛИС чтобы можно было в память писать с девайса. Ну и сопутствующие темы. Думаю твой IP блок должен это уметь, взможно его для этого надо сконфигурить.

slapin ★★★★★
()
Ответ на: комментарий от Vovanano

Хорошо, я пока наверное не буду больше глупых вопросов писать :)

Разобраться бы хотя бы с простейшим write для начала. А там может само станет ясно как дальше...

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от slapin

Хорошо, попробую разобраться. Да, там есть такая фича как bus master и судя по lspci корка эту функцию уже предоставляет.

Просто у меня нетерпение, тока сегодня удалось что-то свое на стороне ПЛИСины оживить и драйвер как-то привязать.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от slapin

И да, инициатива может быть со стороны хоста, можно это делать по записи в регистр, например.

slapin ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.