28 июня 2019 г.

Как скомпилировать Linux для отладочной платы Zybo (Zynq) и запустить его с QSPI

В данной статье будет описано каким образом подготовить все необходимые файлы для запуска Linux с FPGA фирмы Xilinx, а именно отладочной платы Zybo. С последующей записью необходимых файлов на QSPI и запуском готовой системы.

Данное руководство основано на следующих:
instructables.comxilinx-wiki.atlassian.netgithub.com.

Разработка FPGA части будет производиться в Vivado 2019.1, компиляция необходимых файлов для Linux будет выполнена в виртуальной машине Oracle VM VirtualBox, на которой установлена Ubuntu.

Компиляция будет происходить без использования PetaLinux, как утверждают Xilinx - это платформа, которая содержит всё необходимое для запуска Linux на FPGA и облегчает внесение изменений. В данном руководстве всё будет собираться ручным образом, для того чтобы ближе взглянуть на работу встроенных систем.

Процесс загрузки системы описывается следующей схемой, взятой из UG1165 и UG873:

Рис.1 структурная схема загрузки системы
Boot ROM - выполнение инструкций содержащихся в специально отведённой памяти FPGA, они осуществляют изначальную инициализацию, выбирают носитель в котором будет произведён поиск FSBL и запускают его. Изменить этот код нельзя, остальные файлы необходимо подготовить.

Итак начнём.

Первым шагом следует создать проект в Vivado. Для проверки работоспособности платы и корректных настроек можно использовать готовый проект от Xilinx расположенный на github, он реализован на версии 2017.4. Но в данном руководстве используется версия 2019.1 и проект создаётся с нуля. Тем не менее там можно посмотреть правильные настройки для DDR и QSPI.

В отладочной плате Zybo используется XC7Z010CLG400С-1 его и следует выбрать при создании проекта. Xilinx рекомендует использовать готовые библиотеки для своих отладочных плат, при создании проекта, вместо конкретной микросхемы. Как они говорят это облегчает подключение различных интерфейсов, подробное описание здесь. Но для того чтобы не привязываться к конкретным библиотекам выберем отдельно необходимую микросхему.

Рис.2 Выбор микросхемы
Далее нужно создать Block Design. В левом меню, под "IP Integrator", нажимаем "Create Block Design", в создавшемся Block Design добавляем новое IP ядро "Zynq7 processing system", далее жмём в верхней части экрана "Run Block Automation" в появившемся окне нажимаем ok. После выполнения данных действий, процессор должен быть корректно подключен к своим основным выводам.
После этого нужно соединить выводы FCLK_CLK0 и M_AXI_GP0_ACLK, таким образом подаётся частота на AXI интерфейс, он использоваться не будет, но без этого нельзя скомпилировать проект.

Рис.3 IP ядро процессора
В данном руководстве не будет использоваться FPGA часть устройства, необходимо подключить лишь основные компоненты, большая часть из которых соединились автоматически. Но следует корректно настроить параметры тактовой частоты системы, QSPI и RAM память. Для простоты и уменьшения возможности ошибок желательно использовать готовый проект от Xilinx расположенный на github, но тем не менее далее будут приведены изменения которые необходимо сделать вручную при создании нового проекта.

Подключение и используемые компоненты можно посмотреть на схеме, которая находится в открытом доступе.


Двойным щелчком можно открыть настройки IP ядра процессора, для начала в разделе "Clock configuration" выставим корректное значение тактовой частоты процессора. Тактовые сигналы подаются на вывод PS_CLK_500, его и к чему он подсоединяется можно найти на странице 9:

Рис.4 Генератор тактовой частоты процессора
Как видно на процессор подаются тактовые сигналы с частотой 50 МГц.
Выставим это в Vivado:

Рис.5 Настройка тактовой частоты процессора
В качестве RAM используется 2 блока DDR3 памяти "MT41J128M16JT-125" (стр 12):

Рис.6 RAM память
В разделе "DDR Configuration"  следует указать используемую память. Но её не окажется среди доступных, её там нет из-за того, что это устаревшая версия. Новая версия ничем не отличается от предыдущей, но в дополнение может работать при низком напряжении, её код "MT41K128M16JT-125", отличается лишь одной буквой. Её и следует выбрать.

Рис.7 Настройка RAM
Также желательно выставить задержку распространения сигнала, значения из тестового проекта представлены ниже, но начиная с Vivado 2018.1 при сохранении введённых настроек компилятор выдаст предупреждение об отрицательных значениях задержек, подробное описание проблемы находится здесь. Чтобы убрать ошибки нужно отрицательные значения изменить на 0.

Рис.8 Настройка задержек на дорожках печатной платы
Далее следует перейти в "MIO Configuration" изменить "Bank 1 I/O Voltage" на "LVCMOS 1.8V" и в том же окне под "Memory interfaces" поставить галочку напротив "Quad SPI Flash", галочку напротив "Feedback CLK", поменять скорость на fast для всех выводов и отключить "pullup":

Рис.9 Настройка интерфейсов
U-boot сперва настраивает периферию, по умолчанию он будет инициализировать Ethernet, SDIO, из-за этого их нужно подключить, иначе U-boot зависнет. Отключить их можно в исходниках U-boot /configs/zynq_zybo_defconfig. Для конфигурации в Vivado параметры следующие:

Рис.10 Настройка интерфейсов (2)
Рис.11 Настройка интерфейсов (3)
Также для того чтобы общаться с Linux, следует подключить UART:

Рис.12 Настройка интерфейсов (3)
Далее нужно создать HDL wrapper - во вкладке Sources, правой кнопкой на "design_1" и нажать "Create HDL wrapper..." и оставить вариант по умолчанию с автоматическим созданием.

После этого нужно скомпилировать проект. Затем экспортировать его в SDK, нажав File -> Export -> Hardware. В появившемся окне нужно поставить галочку рядом с "Include bitstream" и нажать ок.

Последним шагом следует запустить SDK через File -> Launch SDK. В дальнейшем в Vivado вводить изменения больше не потребуется.

Внутри SDK, нужно создать FSBL. Он установит правильные настройки частоты и DDR вместе с QSPI. Также загрузит все файлы в RAM. Дополнительная информация: Видео от Xilinx про FSBLXilinx wiki FSBLдокументация TRM UG585UG821. Для этого следует создать новый проект File -> New -> Application project.

Рис.13 Создание нового проекта
В появившемся окне ввести имя проекта, нажать Next и выбрать "Zynq FSBL".

Рис.14 Выбор FSBL
FSBL позволяет запустить либо baremetal аппликацию либо сторонний загрузчик который запустит полноценную ОС, в нашем случае используется U-Boot для запуска Linux.

Далее большая часть работы будет происходить в Linux. Также нужно будет переносить файлы между двумя ОС, как это делать в Oracle VM описано здесь.

Все необходимые файлы можно найти на xilinx-wiki.atlassian.net.
Дополнительная информация про U-Boot и про компиляцию: Build U-Boot.
Проще всего скачивать файлы через Git, для того чтобы его установить нужно выполнить:
sudo apt-get install git-core

U-Boot

Чтобы скачать U-Boot, необходимо ввести следующую команду:
git clone https://github.com/Xilinx/u-boot-xlnx.git

После этого в домашней директории появится папка u-boot-xlnx
Необходимо перейти в неё и запустить там командную строку.
cd u-boot-xlnx

Далее выполнить следующие команды
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
make zynq_zybo_config

Если терминал выдаст следующие ошибки:

  YACC    scripts/kconfig/zconf.tab.c
/bin/sh: 1: bison: not found
scripts/Makefile.lib:228: recipe for target 'scripts/kconfig/zconf.tab.c' failed
make[1]: *** [scripts/kconfig/zconf.tab.c] Error 127
Makefile:496: recipe for target 'zynq_zybo_config' failed
make: *** [zynq_zybo_config] Error 2

То необходимо установить пакет bison:
sudo apt-get install bison

и попробовать ещё раз. Успешно выполненная команда выглядит следующим образом:

Рис.15 конфигурация U-Boot
После конфигурации необходимо выполнить команду 
make

Это скомпилирует U-Boot, создаст файл U-Boot.elf в той же директории и утилиту mkimage которые будут использованы в дальнейшем.

Linux

Следующим шагом скомпилируем ядро Linux. Подробнее об этом xilinx-wiki.atlassian.net. Сперва скачаем его используя команду:
git clone https://github.com/Xilinx/linux-xlnx.git

Переходим в созданную директорию:
cd linux-xlnx

Настраиваем ядро:
make ARCH=arm xilinx_zynq_defconfig
make ARCH=arm menuconfig

Откроется меню настроек, если вам не нужны дополнительные изменения, можно просто закрыть окно:

Рис.16 Конфигурация Linux
Запускаем компиляцию командой
make ARCH=arm UIMAGE_LOADADDR=0x8000 uImage

Если вылезет ошибка:
gcc: error: unrecognized argument in option ‘-mabi=aapcs-linux’

необходимо заново выполнить следующую команду:
export CROSS_COMPILE=arm-linux-gnueabihf-

После компиляции в папке 
linux-xlnx/arch/arm/boot
появится файл
uImage
Это и есть скомпилированное ядро.

DTB

Нужно использовать DTB файл, который называется "Device tree". Он описывает Linux какое железо используется, подробнее об этом здесь.

Он уже скомпилированный находится в папке
/u-boot-xlnx/arch/arm/dts/
под названием
zynq-zybo.dtb

Но ради практики скомпилируем новый файл, это делается следующими командами:
cd u-boot-xlnx
./scripts/dtc/dtc -I dts -O dtb -o ./devicetree.dtb ./arch/arm/dts/zynq-zybo.dts 

Если вылезет ошибка:
Error: ./arch/arm/dts/zynq-zybo.dts:7.1-9 syntax error
FATAL ERROR: Unable to parse input tree

Необходимо в dts файле изменить строчку
#include "zynq-7000.dtsi"
на
/include/ "zynq-7000.dtsi"

Терминал не должен ничего вывести при успешном выполнении:

Рис.17 Компиляция device tree
Если всё вышло корректно, должен появится devicetree.dtb файл в папке u-boot-xlnx.

Root File System

Теперь нужно создать файловую систему с которой будет работать Linux, при создании U-boot, также была создана утилита для создания файловой системы.
Сперва нужно скачать файл arm_ramdisk.image.gz, на этой странице также находится более подробное описание данного шага. 
Но всё же, если скачанный файл находится в папке Downloads, то из корневой директории необходимо выполнить:
./u-boot-xlnx/tools/mkimage -A arm -T ramdisk -C gzip -d ./Downloads/arm_ramdisk.image.gz uramdisk.image.gz

При успешном выполнении в корневой директории появится файл uramdisk.image.gz который понадобится в дальнейшем.


BOOT image

Теперь необходимо соединить все файлы вместе и создать загрузочный файл для QSPI. После переноса файлов из Linux в Windows, возвращаемся в SDK и выполняем следующее:
Xilinx -> Create Boot Image

Необходимо добавить все созданные файлы, .bit файл FPGA не обязателен, если нам нужен только процессор. Для всех файлов кроме FSBL, .BIT и U-Boot необходимо указать их расположение в памяти, для этого при добавлении файла ему присваивается offset. По умолчанию при запуске U-Boot с QSPI, адреса следующие: uImage = 0x100000, devicetree = 0x600000, uramdisk.image.gz = 0x620000. Если их указать некорректно, то в терминале будет показана ошибка и корректный адрес. Также их можно посмотреть или изменить в исходниках U-Boot include/configs/zynq-common.h  после
"qspiboot=run xilinxcmd && " \
Либо в руководстве к ZC702.

Также файлы должны быть расположены в правильном порядке, по моменту запуска, в памяти они располагаются друг за другом. Для FSBL в графе Partition type вместо datafile нужно поставить bootloader, в результате должно выглядеть примерно так:

Рис.18 Создание загрузочного образа
Рис.19 Добавление смещения
Для программирования QSPI, нужно выбрать Xilinx -> Programm Flash. В появившемся окне добавить BOOT.bin в Image File и FSBL:

Рис.20 Программирование QSPI
При программировании Zybo следует перевести в режим JTAG. После успешного программирования, плату следует перевести в режим загрузки с QSPI и включить, через terminal подключившись к COM порту, можно следить за выполнением загрузки Linux и в дальнейшем с ним работать.

Рис.21 Linux готовый к работе




3 комментария :

  1. Здравствуйте!
    Установил Vivado 2019.2. В данной версии нет SDK. Как теперь быть?
    Может есть какие-то костыли или что-то ещё подскажете?

    ОтветитьУдалить
  2. Vladimir035
    Здравствуйте. Начиная с версии 2019.2 Vivado является частью среды Vitis.
    Vitis в свою очередь теперь заменяет SDK.
    В общем с версии 2019.2 SDK выпилили.
    Благодарю автора статьи за такое детальное изложение материала и попутные комментарии.

    ОтветитьУдалить
  3. Спасибо, за статью!!
    Изрядно сэкономила время.

    ОтветитьУдалить