Некоторое время назад ко мне в руки попал набор разработчика DE0-Nano-SoC, построенный на базе чипа Altera Cyclone V. Данный набор используется мной не с какой-то одной целью — с его помощью решаются разные задачи. Для каждой из этих задач создаётся схема для FPGA и пишется программа для HPS. Схема для FPGA создаётся в среде Quartus II и в процессе разработки загружается в FPGA через JTAG-интерфейс посредством USB-бластера. Когда же схема окончательно отлажена, она записывается на SD-карточку в виде файла прошивки. Затем, когда нужно использовать плату с той или иной целью, берётся нужная прошивка, загружается в FPGA командой вида
cat hardware.rbf > /dev/fpga0
и затем запускается нужная программа.
Всё шло своим чередом, но однажды я обновил в плате ядро Linux — о чём рассказывал в этой статье. И вот спустя некоторое время обнаружилось, что из списка драйверов исчез FPGA-менеджер, позволявший загружать прошивку в FPGA подобным способом. Первой мыслью было то, что я забыл включить драйвер в конфигурацию при сборке ядра. Однако, к моему удивлению, скоро обнаружилось, что среди исходников ядра этого драйвера нет в принципе! Конечно, можно было бы грузить прошивку в FPGA другими способами, коих есть ещё как минимум три. Но этот способ был для меня наиболее оперативным и удобным, вот почему было принято решение восстановить утраченный функционал. Если Вам интересно, как это было сделано — добро пожаловать под кат.
Небольшое лирическое отступление
Для решения проблемы прежде всего нужно было найти исходные тексты FPGA-менеджера. Естественно, первым делом были обследованы репозитории Альтеры. И опять же я был удивлён тем, что этого драйвера в них не оказалось. Пришлось искать по всему гитхабу и в результате исходники были найдены в репозиториях Терасика. И тут опять образовались грабли: Терасик давно не публиковал ничего на гитхабе и самое свежее ядро было версии 3.12. Как следствие, взятые из этого репозитория исходники FPGA-менеджера отказывались компилироваться под новые ядра из-за того, что в них использовались некоторые «устаревшие» структуры, попросту ликвидированные из новых версий. Переделывать драйвер под новые реалии что-то меня никак не тянуло. Поэтому поиск был продолжен и в конце концов увенчался таки успехом — нашлись адаптированные исходники драйвера в репозитории некоего мистера из Канады с ником xaxaxa. За что ему низкий поклон.
Итак приступим
Подробности сборки ядра можно посмотреть в моей предыдущей статье — далее, чтобы не повторяться, я буду ссылаться на неё время от времени. Всё дальнейшее повествование будет построено на предположении, что весь процесс сборки ядра, описанный в той статье, уже выполнен и все исходники ядра лежат на прежнем месте в целости и сохранности.
1. Запускаем терминалку и входим в root-режим — чтобы не набирать каждый раз команду sudo:
sudo -i
При этом /root будет нашей домашней директорией — всё будем делать в ней.
2. Скачиваем исходники драйвера FPGA-менеджера отсюда и кладём в директорию /root/linux-socfpga-4.1/drivers/fpga/
Также забираем отсюда хидер fpga.h и записываем его в директорию /root/linux-socfpga-4.1/include/linux/
3. Редактируем файл /root/linux-socfpga-4.1/drivers/Kconfig — добавляем в него одну строку:
source "drivers/fpga/Kconfig"
Куда конкретно её добавить — особого значения не имеет. Главное, чтобы она была не самой первой и не самой последней строкой файла. Я добавил её сразу после первой строки. Получилось вот так:
menu "Device Drivers"
source "drivers/fpga/Kconfig"
source "drivers/amba/Kconfig"
...
4. Редактируем файл /root/linux-socfpga-4.1/drivers/Makefile — добавляем в него одну строку:
obj-$(CONFIG_FPGA) += fpga/
Куда конкретно её добавить — опять же значения не имеет. Я добавил её сразу после начальных комментариев. Получилось вот так:
#
# Makefile for the Linux kernel device drivers.
#
# 15 Sep 2000, Christoph Hellwig <hch@infradead.org>
# Rewritten to use lists instead of if-statements.
#
obj-$(CONFIG_FPGA) += fpga/
obj-y += irqchip/
...
5. Запускаем альтеровский скрипт, который запустит новый BASH и подправит в нём некоторые переменные окружения (например, PATH). Все действия по компиляции будем проводить не выходя из этого BASH:
cd /root/altera/15.0/embedded
./embedded_command_shell.sh
6. Создаём несколько переменных окружения:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
export LOADADDR=0x8000
7. Переходим в директорию с исходниками ядра и добавляем драйвер FPGA-менеджера в конфигурацию ядра:
cd /root/linux-socfpga-4.1
make menuconfig
При этом откроется псевдографическое окно с менюшками. Заходим в подменю Device Drivers. Здесь увидим, что на первом месте появилось новое подменю FPGA devices — заходим в него. Внутри будет драйвер FPGA Framework — добавляем его в ядро: нажимаем на нём пробел дважды — при этом напротив него появится символ звёздочки, говорящий о том, что данный драйвер будет встроен в ядро. Сразу после выполнения этих действий в списке появится ещё один драйвер Altera — включаем и его тоже: нажимаем на нём дважды пробел:
Так как мы сейчас не выполняли сброс конфигурации в исходное состояние командой make socfpga_defconfig, то остальные настройки должны остаться в прежнем состоянии — как мы их установили в процессе сборки ядра.
Выходим из меню — нажимаем Exit пока не выйдем. На вопрос — надо ли сохранять конфигурацию — отвечаем Yes.
8. Компилируем ядро:
make uImage
Так как ядро компилировалось нами ранее, то теперь на его пересборку с новыми драйверами уйдёт совсем мало времени.
9. Добавляем в дерево устройств информацию о FPGA-менеджере.
Для этого добавляем в файл /root/linux-socfpga-4.1/arch/arm/boot/dts/socfpga.dtsi следующие строки:
fpgamgr: fpgamgr@0xff706000 {
compatible = "altr,fpga-mgr-1.0", "altr,fpga-mgr";
transport = "mmio";
reg = <0xFF706000 0x1000 0xFFB90000 0x1000>;
interrupts = <0 175 4>;
};
Эти строки можно добавить в блок soc.
...
qspi_clk: qspi_clk {
#clock-cells = <0>;
compatible = "altr,socfpga-gate-clk";
clocks = <&f2s_periph_ref_clk>, <&main_qspi_clk>, <&per_qspi_clk>;
clk-gate = <0xa0 11>;
};
};
};
fpgamgr: fpgamgr@0xff706000 {
compatible = "altr,fpga-mgr-1.0", "altr,fpga-mgr";
transport = "mmio";
reg = <0xFF706000 0x1000 0xFFB90000 0x1000>;
interrupts = <0 175 4>;
};
gmac0: ethernet@ff700000 {
compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
altr,sysmgr-syscon = <&sysmgr 0x60 0>;
reg = <0xff700000 0x2000>;
interrupts = <0 115 4>;
...
10. Конвертируем файл дерева устройств в бинарный формат:
make socfpga_cyclone5_sockit.dtb
11. Копируем ядро и .dtb-файл на карточку в раздел FAT32. Повторяться не буду: о том, как это сделать, подробно описано в подразделе 13 раздела Сборка ядра этой статьи.
На этом всё — процесс сборки ядра в комплекте с драйвером FPGA-менеджера завершён.
Проверка работоспособности
Поставим SD-карточку в плату, загрузимся и проверим работоспособность.
Для этого сначала посмотрим содержимое директории /dev — в ней должен появиться файл драйвера fpga0:
Ну и в завершение загрузим какую-нибудь прошивку в FPGA:
Вуаля! Всё работает как положено.
Всем спасибо за внимание!
This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий