Репозиторий содержит baremetal-приложения для запуска на процессорах ARM CPU0 и MIPS32 RISC0.
Содержание
Для сборки используются тулчейны ARM и RISC. Для RISC должен использоваться тулчейн производства ЭЛВИС (тулчейн реализует обходы аппаратных ошибок ядра).
Оба тулчейна входят в состав MCom-03 Linux SDK. Описание тулчейнов — Средства сборки
Подготовка среды:
wget https://dist.elvees.com/mcom03/buildroot/2023.03/rockpi/images/aarch64-buildroot-linux-gnu_sdk-buildroot.tar.gz tar -xf aarch64-buildroot-linux-gnu_sdk-buildroot.tar.gz source aarch64-buildroot-linux-gnu_sdk-buildroot/environment-setup export MIPS32_CMAKE_TOOLCHAIN_FILE=$PWD/aarch64-buildroot-linux-gnu_sdk-buildroot/opt/toolchain-mipsel-elvees-elf32/share/cmake/toolchain.cmake export ARM_CMAKE_TOOLCHAIN_FILE=$PWD/aarch64-buildroot-linux-gnu_sdk-buildroot/share/buildroot/toolchainfile.cmake
Note
Ссылка на релиз MCom-03 Buidroot приведена справочно. Последняя версия данного репозитория может требовать более свежих версий компиляторов.
Сборка проекта для MIPS32 (RISC0):
cmake -S . -B build-mips -DCMAKE_TOOLCHAIN_FILE=$MIPS32_CMAKE_TOOLCHAIN_FILE make -j -C build-mips
Сборка проекта ARM64 (CPU0):
cmake -S . -B build-arm -DCMAKE_TOOLCHAIN_FILE=$ARM_CMAKE_TOOLCHAIN_FILE make -j -C build-arm
Для проверки форматирования используется pre-commit (см. pre-commit.com):
pre-commit run --all-files
Приложение в бесконечном цикле выводит сообщение "Hello, world!" в UART0 и переключает состояние GPIO1_PORTD_0 (на плате MCom-03 BuB к этому GPIO подключен светодиод HL11).
Приложение собирается в двух (для MIPS) или трёх (для ARM64) вариантах:
- XIP для запуска с QSPI-памяти;
- RAM для запуска через JTAG или при загрузке через консоль UART;
- U-Boot для запуска из U-Boot (доступно только для ARM64).
- Собрать приложение для MIPS32.
- Прошить файл hello-world-mips-xip0.bin на SPI-флеш.
- Подключить SPI-флеш в разъём QSPI0.
- Выставить переключатели BOOT в состояние "000".
- Подать питание на MCom-03.
- Собрать приложение для ARM64.
- Прошить файл hello-world-aarch64-xip1.bin на SPI-флеш.
- Подключить SPI-флеш в разъём QSPI1.
- Выставить переключатели BOOT в состояние "101".
- Подать питание на MCom-03.
Собрать приложение для MIPS32.
Выставить переключатели BOOT в состояние "000" или "011".
Подать питание на MCom-03.
Запустить MDB и выполнить команды:
loadelf <путь_к_файлу>/hello-world-mips-ram.elf set risc.pc 0xa0000000 run
Собрать приложение для ARM64.
Выставить переключатели BOOT в состояние "000" или "011".
Подать питание на MCom-03.
Запустить MDB и выполнить команды:
set 0xbf000020 0x10 loadbin <путь_к_файлу>/hello-world-aarch64-ram.bin 0xa0000000 set 0xbf000000 0x10 set 0xbf001008 0x115 set 0xa1080000 0x2 set 0xa1080004 0x2 set 0xa1080008 0x2 set 0xa1000040 0x10 set 0xa100011C 0x0 set 0xa1000000 0x10
Собрать приложение для MIPS32.
Выставить переключатели BOOT в состояние "011".
Подать питание на MCom-03.
Передать содержимое приложения в накристальное ОЗУ:
cat hello-world-mips-ram.hex > /dev/ttyUSB0
Открыть UART-консоль:
minicom -D /dev/ttyUSB0
В UART-консоли ввести команду:
run
Собрать приложение для ARM64.
Запустить U-Boot. При появлении соощения Hit any key to stop autoboot нажать любую клавишу, что бы перейти в режим командной строки.
Загрузить elf-файл в память любым способом. Например:
через UART0 по протоколу XMODEM:
loadx $loadaddr
с SD-карты:
load mmc 1:1 $loadaddr /spi-flasher-aarch64-uboot.elf
Запустить исполнение elf-файла:
setenv autostart 1 bootelf $loadaddr
Note
В U-Boot доступно только 256 МиБ DDR-памяти в диапазоне от 0x8_9040_0000 до 0x8_A03F_FFFF поэтому загружать elf-файл необходимо в пределах этого диапазона. Следует учитывать, что в верхней части этого диапазона располагается код U-Boot, который нельзя перекрывать. Адрес начала U-Boot можно посмотреть в поле relocaddr, выполнив команду bdaddr. Для избежания повреждения кода U-Boot при загрузке файла рекомендуется использовать адрес из переменной loadaddr. При выполнении команды bootelf elf-файл будет распакован по адресу 0x8_9100_0000.
Приложение предназначено для загрузки в режиме UART0 (BOOT=3) и предоставляет функционал для работы с памятью SPI NOR, подключенной к QSPI0 или QSPI1. Приложение используется скриптом mcom03-flash-tools для прошивки SPI Flash.
Приложение spi-flasher предоставляет консоль через UART0 и может использоваться вручную без mcom03-flash-tools (кроме записи данных, которые передаются в бинарном виде). Для ручного запуска spi-flasher необходимо выполнить следующие действия:
Собрать spi-flasher для архитектуры MIPS (нужен файл spi-flasher-mips-ram.hex).
Выставить переключатели BOOT в состояние "011" и подать питание на MCom-03 (или нажать Reset, если питание уже было подано).
Выполнить:
cat spi-flasher-mips-ram.hex > /dev/ttyUSB0
Открыть UART в любом текстовом терминале (например,
minicom -D /dev/ttyUSB0
).Выполнить команду
run
. После этого начинает исполняться spi-flasher.
Основные команды:
qspi <id> [v18]
<id>
- выбор QSPI0 или QSPI1;[v18]
- выбор напряжения КП QSPI1. Для QSPI0 значение[v18]
игнорируется.[v18]
= 0 - режим 3.3В,[v18]
= 1 - режим 1.8В (например,qspi 1 0
).read <offset> <size> [text|bin]
- чтение содержимого SPI Flash.<offset>
- смещение, начиная с которого читать данные,<size>
- размер данных. Если третий аргумент не указан или указан какtext
, то данные выводятся в текстовом виде. Бинарный вид (bin
) используется только для mcom03-flash-tools. Например,read 0 0x200
.write <offset> <page_size>
- запись данных в SPI Flash, начиная со смещения<offset>
.<page_size>
- размер страницы (можно узнать из описания на микросхему SPI Flash). Для записи используется собственный протокол: Запись данных.erase <offset>
- очистка сектора, начинающегося со смещения<offset>
. Размер сектора зависит от конкретной флеш-памяти (для S25FL128S сектор имеет размер 64 КиБ).readcrc <offset> <size>
- посчитать и вывести в консоль CRC16 для<size>
байт данных, начиная со смещения<offset>
.custom <tx_data> <rx_size>
- отправка на SPI Flash данных<tx_data>
и вывод<rx_size>
байт ответа.<tx_data>
- это набор байт, записанных слитно в 16-ричном представлении. Перед<tx_data>
можно не указывать0x
. Например, командаcustom 0b00020000 64
илиcustom 0x0b00020000 64
отправит на SPI 5 байт[0b, 00, 02, 00, 00]
(команда FAST_READ, адрес 0x200 и один dummy-байт) и прочитает 64 байта ответа.<rx_size>
может быть любым неотрицательным целым числом.bootrom
- прыжок в код BootROM. Это действие выглядит как перезагрузка. Доступно только для сборки под процессор MIPS. Для тестирвоания команды можно использовать следующий код:# загрузить SPI Flasher в память и запустить cat spi-flasher-mips-ram.hex > /dev/ttyUSB0 sleep 1 echo "run" > /dev/ttyUSB0 # проверить, что запускается именно SPI Flasher и он знает команду "bootrom" echo -e "help\r" > /dev/ttyUSB0 & grep "bootrom" /dev/ttyUSB0 sleep 1 # выполнить команду "bootrom" и проверить, что запущена именно консоль BootROM echo -e "bootrom\r" > /dev/ttyUSB0 sleep 1 echo -e "help\r" > /dev/ttyUSB0 & grep "devcommit" /dev/ttyUSB0
exit
- выход в родительскую программу, из которой был вызван spi-flasher. Доступно только для сборки под U-Boot.
Команда write
указывает смещение и размер страницы. Команда возвращает строку:
Ready for data #
После чего ожидает блоки данных. Структура блока:
+--------------------------------------------------+ | len_lo | len_hi | crc_lo | crc_hi | payload .... | +--------------------------------------------------+
len_lo
иlen_hi
- младший и старший байты размера данныхpayload
в байтах (размер блока не должен превышать размер страницы, указанный командойwrite
);crc_lo
иcrc_hi
- младший и старший байты CRC16 от данныхpayload
;payload
- данные для записи.
Если размер указан нулевой размер payload
, то происходит возврат в консоль.
После передачи последнего байта payload
spi-flasher выдаёт один из ответов:
- символ 'R' - означает, что блок записан и spi-flasher ожидаёт следующий блок;
- символ 'C' - означает, что CRC16 от
payload
не соответствует укзанному (данные повредились при передаче через UART). В этом случае запись не производилась и можно либо повторить передачу этого блока, либо прервать запись и вернуться в консоль, указав нулевой размер данных; - строка 'En<сообщение>n' - означает, что произошла ошибка.