Ядро Linux: чтение и запись в область памяти, зарезервированную из дерева устройств.Linux

Ответить
Гость
 Ядро Linux: чтение и запись в область памяти, зарезервированную из дерева устройств.

Сообщение Гость »


Я работаю над uni-проектом, включая плату xilinx fpga. Для нашего PL я зарезервировал немного памяти, следуя руководству на xilinx-wiki. Но похоже, что запись/чтение в/из региона не работает, или я делаю это неправильно. поскольку у меня практически нет опыта работы с ядром Linux, возможно, это второй вариант.

Дерево устройств:

/include/ "system-conf.dtsi" / { зарезервированная память { #адрес-ячейки = ; #размер-ячейки = ; диапазоны; зарезервировано: буфер@0x43c20000 { нет карты; рег = ; }; }; }; &MY_IP_CORE_0 { область-памяти = ; }; Код драйвера для получения памяти:

/* Получить зарезервированную область памяти из дерева устройств */ dev_info(dev, "Получить зарезервированную область памяти из дерева устройств"); np = of_parse_phandle(dev->of_node, "область-памяти", 0); если (!np) { dev_err(dev, "%s не указан\n", "область-памяти"); перейти к ошибке 1; } dev_info(dev, "of_address_to_resource(np, 0, r_dma);"); rc = of_address_to_resource(np, 0, &r_dma); если (RC) { dev_err(dev, "Региону не присвоен адрес памяти\n"); перейти к ошибке 1; } lp->paddr = r_dma.start; lp->vaddr = memremap(r_dma.start, resources_size(&r_dma), MEMREMAP_WB); dev_info(dev, "Выделенная зарезервированная память размером: 0x%0lX, vaddr: 0x%0llX,paddr: 0x%0llX\n", resources_size(&r_dma), (u64)lp->vaddr, (u64)lp->paddr ); Но запись на него не работает.

memset((void *)lp->vaddr, 0x11, 0x64000); dev_info(dev, "Содержимое 0x%0llX после memset: 0x%0llX\n", (u64)lp->vaddr, *(u64 *)lp->vaddr); Чтение из lp->vadr просто возвращает 0.

Вот результат:

mymodule 43c00000.MY_IP_CORE: зондирование дерева устройств mymodule 43c00000.MY_IP_CORE: получить зарезервированную область памяти из дерева устройств. mymodule 43c00000.MY_IP_CORE: of_address_to_resource(np, 0, r_dma); mymodule 43c00000.MY_IP_CORE: выделенная зарезервированная память размером: 0x64000, vaddr: 0xF0B80000, Paddr: 0x43C20000 mymodule 43c00000.MY_IP_CORE: содержимое 0xF0B80000 после memset: 0x0 mymodule 43c00000.MY_IP_CORE: Тест DMA: Старт mymodule 43c00000.MY_IP_CORE: DMA-тест: dma_memcopy — тайм-аут! mymodule 43c00000.MY_IP_CORE: Тест DMA: Передача DMA завершена! mymodule 43c00000.MY_IP_CORE: тест DMA: после передачи DMA: src_buf[0]: 0x12 mymodule 43c00000.MY_IP_CORE: тест DMA: после передачи DMA: lp->vaddr[0]: 0x0 Я попробовал использовать dmaengine для memcpy в регионе, результат тот же.

tatic int test_dma(struct устройство *dev, dma_addr_t dst_addr, void *vaddr) { маска dma_cap_mask_t; структура dma_chan *chan; struct dma_async_tx_descriptor *chan_desc; dma_cookie_t файл cookie; dma_addr_t src_addr; u8 *src_buf, *dst_buf; завершение структуры cmp; международный статус; dev_info(dev, "Тест DMA: Старт\n"); dma_cap_zero (маска); dma_cap_set(DMA_SLAVE | DMA_PRIVATE, маска); chan = dma_request_channel (маска, NULL, NULL); если (!чан) { dev_err(dev, "DMA-Test: Ошибка запроса канала DMA\n"); возврат -ЕНОДЕВ; } src_buf = dma_alloc_coherent (dev, 1024, &src_addr, GFP_KERNEL); если (!src_buf) { dev_err(dev, "Тест DMA: Ошибка выделения когерентной памяти\n"); возврат -ЭНОМЕМ; } memset (src_buf, 0x12, 1024); chan_desc = dmaengine_prep_dma_memcpy(chan, dst_addr, src_addr, 1024, DMA_MEM_TO_MEM); если (!chan_desc) { dev_err(dev, "DMA-Test: Ошибка запроса канала DMA\n"); статус = -1; перейти бесплатно; } init_completion(&cmp); chan_desc-> обратный вызов =thanna_dma_transfer_completed; chan_desc->callback_param = &cmp; cookie = dmaengine_submit (chan_desc); dma_async_issue_pending (чан); if (wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000))
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»