Настройка Linux на макетной плате, такой как SocKit, с двухъядерным процессором ARM Cortex A9 — это не высшая математика. Производитель платы поддерживает готовый образ, подходящий для установки на SD-карту или другой носитель. Но что, если вы жаждете прикоснуться к голому железу, приближаясь к головокружительной скорости кода, не сдерживаемого ядром ОС? Что ж, это возможно, но не так просто и очевидно. В этом коротком эссе я дам вам пошаговую инструкцию, как собрать и запустить ваше первое «голое железо» приложение на SoC Cyclone V, которое использует ядро ​​ARM Cortex A9 подсистемы HPS SoC.

У вас должна быть плата для разработки с процессором Intel (Altera) Cyclone V SoC. Я использовал плату SoCKit:

Я делал все, что описано в этой статье, в Debian Jessie. Вы можете использовать другую систему Linux или Windows с соответствующими изменениями.

И вам нужна DS-5 IDE. И, к сожалению, бесплатная версия не позволяет скомпилировать «голый» код. Вам нужна полная версия.

1. Подготовка

Несмотря на то, что у вас есть полная версия DS-5, вам необходимо установить бесплатную версию DS-5 Altera Edition. Обе версии должны быть установлены в режиме sudo, в разные каталоги, например: /home/user/intelFPGA для DS-5 Altera Edition и /home /user/DS-5 для получения полной версии DS-5. Вы должны ввести пути вручную в процессе установки.

2. Работа IDE

2.1. Сначала запустите скрипт /home/user/intelFPGA/16.1/embedded/embedded_command_shell.sh, затем измените каталог на /home/user/DS-5/bin и запустить IDE:

$ ./eclipse &

Сценарий устанавливает переменные среды. Для установки переменных при запуске системы необходимо добавить в файл /home/user/.profile следующую строку:

QUARTUS_ROOTDIR=/home/user/intelFPGA/16.1/qprogrammer export PATH=$PATH:/usr/local/gcc-arm-none-eabi-5_4-2016q3/bin/:/home/user/intelFPGA/16.1/embedded/host_tools/mentor/gnu/arm/baremetal/bin/

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

Также вам необходимо установить и запустить Quartus Prime. Предположим, что каталог установки Quartus — /home/user/intelFPGA/16.1/quartus/.

Запустите Quartus Prime, расположенный по адресу /home/user/intelFPGA/16.1/quartus/bin/quartus, и его утилиту для программирования JTAG, расположенную по адресу /home/user/intelFPGA/16.1/. qprogrammer/bin/quartus_pgmw.

3. Подключение SoCkit

3.1. Подключите плату SoCkit к компьютеру. Подключите кабели microUSB к портам платы с названиями «USB Blaster (JTAG)» и «USB to UART».

3.2. Включите доску и введите:

$ ls /dev/bus/usb/001
 001  002  003

Последний номер (003) — это интерфейс JTAG. Установить права на запись:

$ sudo chmod 666 /dev/bus/usb/001/003

Вы должны делать это каждый раз, когда вы включаете доску.

3.3. Настройки терминала TTY

Вы можете использовать эту команду:

screen /dev/ttyUSB0 115200

4. Сборка прелоадера (u-boot-spl)

4.1. Загрузите файл sockit_ghrd_16.0.tar.gz и распакуйте его. Например, распакуйте его в папку /home/user/ghrd-16/sockit_ghrd.

4.2. Запустите Quartus Prime и откройте файл /home/user/ghrd-16/sockit_ghrd/soc_system.qpf.

4.3. Запустите Qsys (Инструменты/Qsys). Откройте файл /home/user/ghrd-16/sockit_ghrd/soc_system.qsys. Выполните Generate/Generate HDL и закройте Qsys.

4.4. Запустите Ассемблер в Quartus Prime.

4.5. Запустите bsp-editor: /home/user/intelFPGA/16.1/embedded/host_tools/altera/preloadergen/bsp-editor. Создайте новый проект: File/New HPS BSP. В поле «Каталог настроек Preloader» напишите «/home/user/ghrd-16/sockit_ghrd/hps_isw_handoff/soc_system_hps_0.»

4.6. Настройте прелоадер. Перейдите на вкладку Дополнительно. Отключите Watchdog_enable. Если вы хотите видеть отладочные сообщения через JTAG, вы можете включить Semihosting. После этого нажмите Создать и выйдите.

4.7. Можно изменить стартовое сообщение. Например, в файле software/spl_bsp/uboot-socfpga/board/altera/socfpga/socfpga_cyclone5.c меняем строку «BOARD: Altera SOCFPGA Cyclone V Board» на другую:

/*
 * Print Board information
 */
int checkboard(void)
{
#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
 puts("BOARD : Altera VTDEV5XS1 Virtual Board\n");
#else
 //puts("BOARD : Altera SOCFPGA Cyclone V Board\n");
 puts("ARM preloader build by 32-bit.me\n");
#endif
 return 0;
}

4.8. Переменная среды SOCEDS_DEST_ROOT должна иметь значение /home/user/intelFPGA/16.1/embedded:

export SOCEDS_DEST_ROOT=/home/user/intelFPGA/16.1/embedded

Теперь перейдите в каталог

/home/user/ghrd-16/sockit_ghrd/software/spl_bsp

и выполните сделать. Make может завершиться ошибкой «make: mkpimage: Command not found», но он должен собрать файл u-boot-spl по пути /home/user/ghrd-16/sockit_ghrd. /software/spl_bsp/uboot-socfpga/spl/u-boot-spl.

4.9. Тестирование прелоадера

4.9.1. Вам не нужен образ FPGA (с расширением «.sof») для запуска предварительного загрузчика. Запустите DS-5 и откройте «Выполнить/Отладить конфигурации».

4.9.2. В поле Соединение необходимо установить параметр CV SoCKit 1–1. Если это не так, нажмите кнопку «Обзор» и установите эту опцию. При появлении ошибки выполните 3.1–3.2.

4.9.3. Установите файл u-boot-spl на вкладке «Файлы», в поле «Приложение на хосте для загрузки»: /home/user/ghrd-16/sockit_ghrd/software/spl_bsp/uboot-socfpga/ spl/u-boot-spl. Установите флажок «Загрузить символы». Оставьте поле «Файлы» пустым.

4.9.4. Отключите запуск скрипта отладки на вкладке Отладка.

4.9.5. Запустите терминальную утилиту (например, screen) и нажмите кнопку «Отладка». Предварительный загрузчик загружается в память, и отладчик готов к запуску. Нажимаем кнопку «Продолжить» (или F8) и видим сообщение:

U-Boot SPL 2013.01.01 (Jun 24 2017 - 19:49:33)
ARM preloader build by 32-bit.me
CLOCK: EOSC1 clock 25000 KHz
CLOCK: EOSC2 clock 25000 KHz
CLOCK: F2S_SDR_REF clock 0 KHz
CLOCK: F2S_PER_REF clock 0 KHz
CLOCK: MPU clock 925 MHz
CLOCK: DDR clock 400 MHz
CLOCK: UART clock 100000 KHz
CLOCK: MMC clock 50000 KHz
CLOCK: QSPI clock 370000 KHz
RESET: COLD
SDRAM: Initializing MMR registers
SDRAM: Calibrating PHY
SEQ.C: Preparing to start memory calibration
SEQ.C: CALIBRATION PASSED
SDRAM: 1024 MiB
ALTERA DWMMC: 0
Card did not respond to voltage select!
spl: mmc init failed: err - -17
### ERROR ### Please RESET the board ###

Это означает, что прелоадер успешно запустился.

4.9.6. После сеанса отладки нажмите кнопки «Отключиться от цели» и «Удалить соединение».

5. Напишите Hello World для режима «голого железа».

5.1. Загрузите проект ArrowSocKit_BareMetal_GNU.zip. Установите переменные среды, как в 2.1., запустите DS-5, импортируйте проект из архива (Файл/Импорт/Существующий проект в рабочую область, Выбрать архивный файл). Распакованный проект появится в каталоге /home/user/DS-5-Workspace/BareMetalBoot-GNU.

5.2. Вы можете попытаться собрать проект с помощью make, но он пока не может быть собран. Чтобы построить проект, выполните следующие действия.

5.3. Скопируйте каталог /home/user/intelFPGA/16.1/embedded/ip/altera/hps/altera_hps/hwlib в /home/user/DS-5-Workspace/. Здесь находятся папки src и include, а в каждой из них есть каталоги soc_cv_av и soc_a10. Вы можете удалить каталоги с именем soc_a10. Затем скопируйте файлы libcs3.a, libcs3arm.a, libcs3unhosted.a из /home/user/intelFPGA/16.1/embedded/host_tools/mentor/gnu/arm/baremetal/arm-altera-eabi/lib. в каталог проекта (/home/user/DS-5-Workspace/BareMetalBoot-GNU). Скопируйте файл arm-names.inc из /home/user/intelFPGA/16.1/embedded/host_tools/mentor/gnu/arm/baremetal/arm-altera-eabi/lib/cortex-a9/ в /home/user/DS-5-Workspace/BareMetalBoot-GNU/.

5.4. В Makefile измените «CROSS_COMPILE := arm-none-eabi-» на «CROSS_COMPILE := arm-altera-eabi-». Также измените путь на hlib: HWLIBS_ROOT := /home/user/DS-5-Workspace/hwlib

5.5. Теперь запустите make. и прочитайте все сообщения об ошибках. Если make не может найти какой-либо символ, вам следует найти его в каталогах hwlib/src/soc_cv_av и hwlib/include/soc_cv_av и сделать копию в hwlib/src и hwlib/include соответственно. После того, как вы найдете все фалы, make вылетает с ошибкой «mkimage: not found», но это не важно, ведь нам нужен только файл test.axf.

5.6. Запуск приложения

5.6.1. Для запуска приложения необходимо загрузить образ FPGA (файл .sof), который был сгенерирован при сборке предварительного загрузчика. Запустите программатор, как мы это делали в 2.1. Справа от нижней части «Настройка оборудования» должен быть текст «CV SoCKit [1-1]». Если его нет, вы должны установить разрешение на запись для порта JTAG (см. выше) и нажать кнопку «Настройка оборудования».

5.6.2. Нажмите «Автоопределение» и выберите произвольный вариант из списка. Вы видите конфигурацию из двух устройств: одно — то, что вы выбрали (например, 5CSEBA6), а второе — SOCVHPS. Удалите первое устройство: выберите его и нажмите Удалить. Нажмите «Добавить файл» и откройте файл образа (/home/user/ghrd-16/sockit_ghrd/output_files/soc_system.sof). Справа от SOCVHPS появилось новое устройство. Переместите его мышкой на первое место в цепочке. После этого нажмите Start и загрузите изображение.

5.6.3. В DS-5 откройте «Debug Configuration» на вкладке «Files». Установите файл u-boot-spl в строке «Приложение на хосте для загрузки». Снимите отметку «Загрузить символы». Установите файл «test.axf» в строку «Файлы». На вкладке «Отладчик» установите флажок «Выполнить сценарий отладчика инициализации целевого объекта» и установите файл сценария «debug-unhosted.ds», расположенный в каталоге проекта. В файле отредактируйте путь к прелоадеру:
# Load the SPL preloader into memory.
#
loadfile "/home/user/ghrd-16/sockit_ghrd/software/spl_bsp/uboot-socfpga/spl/u-boot-spl" 0x0

Запустите экран терминала TTY и нажмите «Отладка». Затем запустится прелоадер, загрузится приложение и будет установлен отладчик на стартовую точку программы. Нажмите кнопку «Продолжить». В окне терминала вы увидите вывод прелоадера, как было показано выше, а затем следующее:

Disabled interrupts because preloader enabled ECC interrupts.
Global Timer value at startup = 0x000000005A10B609
CPU frequency is 925000000 hertz.
DDR frequency is 400000000 hertz.
MPU peripheral frequency is 231250000 hertz.
MB ZERO remapped to SDRAM.
L3 interconnect remapped as inaccessible and SDRAM.
Interrupt controller system API initialized.
MMU initialized and enabled.
L1 and L2 cache system initialized and enabled.
GIC interrupts enabled.
PIT started.
PIT interrupt registered and enabled.
GPIOs initialized.
UART0 initialized.
L3 interconnect remapped as accessible and SDRAM.
Bridges initialized.
Boot completed.
Boot milestones:
New buffer !ESTONE :       GT TICKCOUNT :  INCREMENTAL :   CUMULATIVE
        initial GT : 0x000000005A10B609 :      0.000us :      0.000us
 frequency capture : 0x000000005A119D58 :    256.065us :    256.065us
 initial remapping : 0x000000005A11C936 :     48.562us :    304.627us
interrupt sys init : 0x000000005A139FED :    521.094us :    825.721us
          mmu init : 0x000000005A62D774 :  22449.985us :  23275.706us
        cache init : 0x000000005A65CF96 :    841.488us :  24117.194us
interrupts enabled : 0x000000005A65D0D7 :      1.388us :  24118.582us
         pit start : 0x000000005A65DD2E :     13.661us :  24132.242us
       pit enabled : 0x000000005A65DF67 :      2.461us :  24134.703us
         gpio init : 0x000000005A65FC12 :     31.736us :  24166.439us
        uart0 init : 0x000000005A66084D :     13.539us :  24179.978us
       fpga config : 0x0000000000000000 : 79769704095969360.000us : 79769704095993552.000us
    last remapping : 0x000000005A660981 : 6558428.303us :  24181.310us
       bridge init : 0x000000005A6611B6 :      9.085us :  24190.396us
          complete : 0x000000005A661222 :      0.467us :  24190.863us
Hello world, 32bit-me!

Поздравляем! Вы только что запустили свое первое приложение на «голом железе» на ядре Cortex-A9.