Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Linux PCI-DMA


Автор: arcades 19.1.2008, 21:14
Пишу драйвер для передачи данных с памяти на плате через шину PCI express и запись в файл,
Стандартное считывание было с медленной скоростью, поэтому решил делать через DMA-функции,
Нашел в интернете следующий текст:
-----------------------------
Dynamic DMA Mapping

Direct memory access in Linux for AMD64 technology requires the use of the dynamic DMA mapping API. This API provides a way to efficiently map 64-bit physical addresses to 32-bit Single Address Cycle PCI addresses, so that hardware that only supports 32-bit accesses can be used in 64-bit systems. A full description of the dynamic DMA mapping API is beyond the scope of this document. Device driver developers who need to use DMA should read DMA-mapping.txt in the /usr/src/linux/Documentation directory.

Нашел у себя эту документацию и прочитал. Там было написано что главным является добавление 
Код

#include <linux/pci.h>

Код программы:
Код

#include <linux/pci.h>
#include <pci/pci.h>
#include <stdio.h>
#include <sys/mman.h> 
int main (int argc, char *argv[]) {
    struct pci_dev *dev;
    u64 device_mask;
    struct pci_dev *pdev;
    int pci_dma;
    int pci_consistent;
    pci_dma = pci_set_dma_mask(*pdev, device_mask);
    pci_consistent = pci_set_consistent_dma_mask(*pdev, device_mask);
    return 0;
}


Код

# gcc -o beta beta.c -lpci -lz
beta.c:(.text+0xa4): undefined reference to `pci_set_dma_mask'
beta.c:(.text+0xec): undefined reference to `pci_set_consistent_dma_mask'
collect2: ld returned 1 exit status

Вот что выдал компилятор,
Тоесть эти функции в pci.h не определены,
Поискал на компьютере заголовочные файлы содержащие эти функции;
>> Выяснилось что функции DMA описаны в следующих файлах:
Код

/usr/src/linux-source-2.6.22/include/linux/PCI.h
/usr/src/linux-headers-2.6.22-14-generic/include/linux/PCI.h
/usr/src/linux-headers-2.6.22-14/include/asm-generic/pci-dma-compat.h
/usr/src/linux-headers-2.6.22-14/include/asm-generic/dma-mapping.h
/usr/src/linux-source-2.6.22/include/asm-i386/dma-mapping.h
/usr/src/linux-source-2.6.22/include/asm-i386/pci.h

--------------------------------
Теперь суть проблемы: стандарно 
Код

#include </usr/src/linux-source-2.6.22/include/asm-i386/dma-mapping.h>
dma-mapping.h добавить нельзя, потамучто внутри него прописаны другие заголовки типа такого:

dma-mapping.h source:
.................................
Код

#include <asm/cache.h>
#include <asm/io.h>
#include <asm/scatterlist.h>
#include <asm/bug.h>

.................................

которые компилятор уже не найдет, а внутри этих прописаны следющие и так до бесконечности,
-------------------------------------------------------------------------------------------------------------

Вопросы: 

1) Есть ли какой-то способ добавить эти заголовки внутри кода программы или при компиляции?
2) Если нужно для этого написать специальный Makefile какой может быть простой пример для компиляции программы и автоматического добавления заголовочных файлов?

Старался изложить как можно подробнее суть проблемы, Жду ответов, заранее благодарен за помощь спецам!

Автор: JackYF 19.1.2008, 21:25
man gcc, опция -I определяет пути к заголовочным файлам.

Автор: MAKCim 19.1.2008, 21:45
Цитата(arcades @  19.1.2008,  21:14 Найти цитируемый пост)
Тоесть эти функции в pci.h не определены,

у тебя ошибка компоновки
+ как раз в <linux/pci.h>
прототипы этих функций определены
сами функции определены в ядре, поэтому для их использования надо писать модуль ядра


Добавлено через 46 секунд
также используйте тег код

Автор: bilbobagginz 19.1.2008, 22:27
Цитата(arcades @  19.1.2008,  21:14 Найти цитируемый пост)
1) Есть ли какой-то способ добавить эти заголовки внутри кода программы или при компиляции?

да, только это тоже не сработает.

Цитата(arcades @  19.1.2008,  21:14 Найти цитируемый пост)
2) Если нужно для этого написать специальный Makefile какой может быть простой пример для компиляции программы и автоматического добавления заголовочных файлов?

да. 
идея: вы должны написать код загружаемого модуля ядра, т.е. lkm (loadable kernel module).
этот процесс описан в объяснениях как создавать модули, с примерами Makefile-ов.
по идее там просто другие флажки передаются к gcc, а также формат модуля.
пройдитесь по http://tldp.org/LDP/lkmpg/2.6/html/x181.html в частности, и по http://tldp.org/LDP/lkmpg/2.6/html/index.html вообще.




удачи.



Автор: arcades 21.1.2008, 19:18
Благодарю за ценные ответы. А вообще есть ли уже написанные модули для этих функций чтобы самому не писать?

Автор: MAKCim 21.1.2008, 21:45
Цитата(arcades @  21.1.2008,  19:18 Найти цитируемый пост)
Благодарю за ценные ответы. А вообще есть ли уже написанные модули для этих функций чтобы самому не писать? 

модуль нужен не для реализации функций (они уже реализованы), а для их использования
вообще, как-то странно, собрался писать драйвер, а такие вопросы задаешь

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)