Драйвер устройства ядра Linux для DMA в пространство ядра - PullRequest
8 голосов
/ 06 апреля 2011

LDD3 (p: 453) demos dma_map_single с использованием буфера, переданного в качестве параметра.

bus_addr = dma_map_single(&dev->pci_dev->dev, buffer, count, dev->dma_dir);

Q1 : Что / откуда этот буфер?

kmalloc

Q2 : Почему DMA-API-HOWTO.txt указывает, что я могу использовать raw kmalloc для DMA в?

Форма http://www.mjmwired.net/kernel/Documentation/DMA-API-HOWTO.txt

L: 51 Если вы приобрели свою память через распределитель страниц kmalloc (), вы можете отправлять DMA в / из этой памяти, используя адреса, возвращаемые этими подпрограммами.

L: 74 вы не можете получить возврат вызова kmap () и прямого доступа к памяти в / из этого.

  1. То есть я могу передать адрес, возвращенный с kmalloc, на мое аппаратное устройство?
  2. Или я должен сначала запустить virt_to_bus на нем?
  3. Или я должен передать это в dma_map_single?

Q3 : Когда передача DMA завершена, могу ли я прочитать данные в драйвере ядра по адресу kmalloc?

addr = kmalloc(...);
...
printk("test result : 0x%08x\n", addr[0]);

Q4 : Каков наилучший способ получить это в пространстве пользователя?

  1. copy_to_user
  2. mmap память kmalloc?
  3. другие

1 Ответ

16 голосов
/ 06 апреля 2011
  1. kmalloc действительно является одним источником для получения буфера. Другой может быть alloc_page с флагом GFP_DMA.

  2. Смысл в том, что память, которую возвращает kmalloc, гарантированно будет непрерывной в физической памяти, а не только в виртуальной памяти, поэтому вы можете указать адрес шины этого указателя для вашего оборудования. Вам нужно использовать dma_map_single () для возвращенного адреса, который в зависимости от конкретной платформы может быть не более, чем обертка вокруг virt_to_bus или может делать больше, чем делать (настроить таблицы IOMMU или GART)

  3. Правильно, просто следуйте рекомендациям по когерентности кэша, как объясняет руководство по DMA.

  4. copy_to_user будет работать нормально и является самым простым ответом. В зависимости от вашего конкретного случая этого может быть достаточно, или вам может понадобиться что-то с лучшей производительностью. Вы не можете обычно сопоставлять kmalloced адреса с пользовательским пространством, но вы можете DMA в предоставленный пользователем адрес (применяются некоторые предостережения) или распределять пользовательские страницы (alloc_page with GFP_USER)

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...