Неизвестный символ flush_cache_range в драйвере устройства Linux

#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.