#linux-kernel #linux-device-driver
#linux-ядро #linux-device-driver
Вопрос:
Я только что написал свой самый первый драйвер устройства Linux, и я столкнулся с проблемой. Я хочу предотвратить кэширование одной области памяти, поэтому я пытался использовать flush_cache_range()
и flush_tlb_range()
для очистки кэша для этой области памяти. Все компилируется хорошо, но при попытке загрузить модуль ядра я получаю следующие ошибки:
Unknown symbol flush_cache_range (err 0)
Unknown symbol flush_tlb_range (err 0)
Я нахожу это очень странным. Разве они не должны быть определены в ядре?
Я знаю, что в качестве альтернативы я мог бы также использовать dma_alloc_coherent()
для выделения некэшированной области памяти. Но у меня нет структуры устройства, и передача значения NULL для этого параметра не вызвала никаких ошибок, но я также не смог увидеть ни одной из данных, которые должны были там быть.
Некоторая информация о моей системе: Я пытаюсь запустить это на микроконтроллере ARM со встроенной FPGA (Xilinx Zynq). FPGA копирует некоторые данные в ячейку памяти, указанную процессором. Теперь я хочу получить доступ к этой памяти, не получая старые данные из кэшей.
Любая помощь очень ценится.
Ответ №1:
Вы не можете использовать такие функции, как flush_cache_range()
поскольку они не предназначены для использования модулями.
Чтобы выделить память, доступ к которой может получить устройство DMA, вы должны использовать dma_alloc_coherent()
. Для этого требуется действительная структура устройства, чтобы оно могло выполнять правильное сопоставление адресов памяти и шин.
Если ваше устройство не подключено к шине, которая обрабатывается существующей платформой (такой как PCI), вам необходимо создать платформенное устройство.
Комментарии:
1. Спасибо, я думаю, что наконец-то запустил его, даже без структуры устройства. Похоже, это работает при передаче нулевого указателя для устройства. На самом деле моя проблема была в другом месте.
Ответ №2:
Несколько замечаний:
1- flush_cache_range не «предотвращает кэширование одной области памяти» .. Он просто очищает (clean invalidate) кэши. Любая последующая запись / считывание в эту область памяти через тот же виртуальный диапазон будет проходить через кэш снова.
2- Если FPGA выполняет запись в память, а затем центральный процессор собирается считывать данные из этой памяти, вероятно, очистка кэша в любом случае является неправильной. Обычно то, что вам нужно сделать, это сделать область памяти недействительной, а затем указать FPGA на запись.
3- Пожалуйста, взгляните на «$ {kernel-src}/Documentation/DMA-API.txt » в исходных текстах ядра. В нем содержится множество информации о том, как вы можете безопасно (обслуживание кэша перевод phys_to_dma ) использовать определенную область памяти для DMA.