Предоставленная Imagination Technologies документация на MIPSfpga очень хорошо и подробно описывает развертывание Linux. Но используемая при этом система на кристалле построена с помощью Xilinx-специфических периферийных модулей. Потому ее повторение на отладочной плате с ПЛИС Altera в исходном виде представляется невозможным. Решением является система на кристалле MIPSfpga-plus с ее платформонезависимой периферией. О том, как запустить на ней Linux, читайте в этой статье.
Введение
Сразу отметим, что получаемой в результате описанных ниже действий конфигурации пока что далеко от идеала. На данный момент нет загрузки с внешнего носителя, а в числе поддерживаемых устройств можно упомянуть только UART и GPIO. Поэтому фронт дальнейшей работы по развитию системы MIPSfpga-plus представляется очень широким.
Далее предполагается, что читатель:
- знаком с предметной областью в объеме учебника Харрис-энд-Харрис [L1];
- имеет доступ к исходным кодам MIPSfpga [L2] и mipsfpga-plus [L3];
- настроил и проверил работу MIPSfpga-plus с SDRAM [L5] и UART [L6], а также в режиме удаленной отладки [L4];
- имеет некоторые навыки использования средств разработки ОС Linux, опыт работы с git;
В описываемом случае используется следующая конфигурация:
- отладочная плата Terasic DE10-Lite с ПЛИС Altera MAX10 и SDRAM 64Mб на борту;
- плата Pinboard II в качестве отладчика и UART-конвертера. Вы можете использовать любую плату с FTDI USB-чипом, поддерживающим MPSSE, пример такой конфигурации описан в [L4];
- компьютер Windows 7 (x64) и Quartus Prime 16.1 для синтеза и программирования ПЛИС;
- виртуальная машина с Ubuntu 17.04 (x64) для сборки ядра и RAM-образа файловой системы;
- доступ в Интернет;
В случае, если вы планируете серьезно и глубоко погрузиться в магию ядра Linux, настойчиво рекомендуется ознакомится с материалами [L7], в частности, с презентациями [L8] и [L9].
Если все перечисленные требования выполнены, начнем!
Синтез конфигурации и программирование ПЛИС
в настройках MIPSfpga-plus (файл mfp_ahb_lite_matrix_config.vh) должны быть включены периферийные модули работы с SDRAM и UART, а также отладка через MPSSE — если используется механизм отладки, описанный в [L4]:
`define MFP_USE_SDRAM_MEMORY `define MFP_USE_DUPLEX_UART `define MFP_USE_MPSSE_DEBUGGER
- с помощью Quartus выполнить сборку MIPSfpga-plus и программирование ПЛИС;
Сборка ядра и RAM-диска
Предполагается, что дальнейшие действия выполняются на машине под управлением Linux.
обновить список доступных для системы пакетов:
sudo apt-get update
установить утилиты и библиотеки, необходимые для конфигурирования и сборки:
sudo apt-get install -y build-essential git libncurses5-dev bc unzip
создать каталог, в котором будет идти вся дальнейшая работа и перейти в него:
mkdir ~/mipsfpga cd ~/mipsfpga
выполнить загрузку toolchain с сайта Imagination Technologies:
wget http://codescape-mips-sdk.imgtec.com/components/toolchain/2016.05-06/Codescape.GNU.Tools.Package.2016.05-06.for.MIPS.MTI.Linux.CentOS-5.x86_64.tar.gz
создать каталог и развернуть в нем скачанный пакет:
mkdir ~/mipsfpga/toolchain tar -xvf Codescape.GNU.Tools.Package.2016.05-06.for.MIPS.MTI.Linux.CentOS-5.x86_64.tar.gz -C ~/mipsfpga/toolchain
желательно (но не обязательно) прописать путь к развернутым исполняемым файлам в переменную $PATH, это упростит работу с ними. Например, в ~/.profile
pathadd() { if [ -d "$1" ] && [[ ":$PATH:" != *":$1:"* ]]; then PATH="$1${PATH:+":$PATH"}" fi } pathadd "$HOME/bin" pathadd "$HOME/.local/bin" pathadd "$HOME/mipsfpga/toolchain/mips-mti-linux-gnu/2016.05-06/bin"
получаем ядро Linux:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git kernel
получаем buildroot, с помощью которого будет сформирован RAM-образа файловой системы:
git clone git://git.buildroot.net/buildroot
создаем каталог для патчей buildroot и Linux, необходимых для развертывания на MIPSfpga-plus:
mkdir patches
скачиваем патчи [L10], сохраняем их в только что созданном каталоге;
переходим в каталог с buildroot и откатываемся на версию 2017.05.1 (коммит f3d8beeb3694):
cd buildroot git checkout 2017.05.1
применяем патч к buildroot:
git apply ../patches/MIPSfpga_buildroot.patch
выполняем конфигурирование buildroot:
make xilfpga_static_defconfig
при необходимости вносим изменения в конфигурацию:
make menuconfig
запускаем сборку RAM-образа файловой системы и идем пить вкусный кофе (чай, пиво или кто что любит), т.к. процесс это весьма продолжительный:
make
переходим в каталог с ядром Linux и проверяем, что RAM-образа файловой системы находится по ожидаемому нами пути (в дальнейшем нам необходимо будет указать его в конфигурации ядра):
cd ../kernel/ ls -l ../buildroot/output/images/rootfs.cpio
откатываемся на версию v4.12.1 (коммит cb6621858813), т.к. именно от нее сформирован патч:
git checkout v4.12.1
применяем патч:
git apply ../patches/MIPSfpga_linux.patch
применяем базовую конфигурацию ядра MIPSfpga:
make ARCH=mips xilfpga_de10lite_defconfig
запускаем редактор конфигурации:
make ARCH=mips menuconfig
- включаем поддержку RAM-диска и прописываем к нему путь (ранее мы проверяли существование этого файла):
- сохраняем изменения, выходим из графического конфигуратора и запускаем сборку ядра:
make ARCH=mips CROSS_COMPILE=~/mipsfpga/toolchain/mips-mti-linux-gnu/2016.05-06/bin/mips-mti-linux-gnu-
Загрузка ядра в память и запуск
- на машине, к которой подключен аппаратный отладчик, запускаем OpenOCD, например так, как это описано в [L4];
- на этой же машине запускаем терминал (например, PuTTY) и подключаемся к COM-порту (скорость 115200);
на Linux-компьютере, где мы выполняли сборку, запускаем gdb из состава MIPS toolchain. Предполагается, что мы находимся в каталоге с собранным ядром:
mips-mti-linux-gnu-gdb ./vmlinux
Дальнейшие действия выполняются в консоли gdb.
подключаемся к OpenOCD, который запущен на машине с аппаратным отладчиком:
(gdb) target remote 192.168.Х.Х:3333
выполняем сброс системы MIPSfpga:
(gdb) mo reset halt
сообщаем отладчику, что наша система Little Endian:
(gdb) set endian little
загружаем образ ядра в память:
(gdb) load
запускаем ядро на выполнение:
(gdb) continue
- если все сделано правильно, то через некоторое время в ранее запущенном терминале мы должны увидеть лог загрузки, похожи на приведенный ниже. В связи с особенностью текущей конфигурации ядра он появится не сразу, а спустя небольшую задержку.
Linux version 4.12.1+ (stas@ubuntu) (gcc version 4.9.2 (Codescape GNU Tools 2016.05-06 for MIPS MTI Linux) ) #1 Sat Jul 22 14:35:05 MSK 2017
CPU0 revision is: 00019e60 (MIPS M14KEc)
MIPS: machine is terasic,de10lite
Determined physical RAM map:
memory: 04000000 @ 00000000 (usable)
Initrd not found or empty - disabling initrd
Primary instruction cache 4kB, VIPT, 2-way, linesize 16 bytes.
Primary data cache 4kB, 2-way, VIPT, no aliases, linesize 16 bytes
Zone ranges:
Normal [mem 0x0000000000000000-0x0000000003ffffff]
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x0000000000000000-0x0000000003ffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x0000000003ffffff]
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: console=ttyS0,115200
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 60512K/65536K available (1830K kernel code, 99K rwdata, 320K rodata, 944K init, 185K bss, 5024K reserved, 0K cma-reserved)
NR_IRQS:8
clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 38225208935 ns
sched_clock: 32 bits at 50MHz, resolution 20ns, wraps every 42949672950ns
Console: colour dummy device 80x25
Calibrating delay loop... 10.81 BogoMIPS (lpj=21632)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
futex hash table entries: 256 (order: -1, 3072 bytes)
clocksource: Switched to clocksource MIPS
random: fast init done
workingset: timestamp_bits=30 max_order=14 bucket_order=0
Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
console [ttyS0] disabled
b0400000.serial: ttyS0 at MMIO 0xb0401000 (irq = 0, base_baud = 3125000) is a 16550A
console [ttyS0] enabled
Freeing unused kernel memory: 944K
This architecture does not have kernel memory protection.
mount: mounting devpts on /dev/pts failed: No such device
mount: mounting tmpfs on /dev/shm failed: Invalid argument
mount: mounting tmpfs on /tmp failed: Invalid argument
mount: mounting tmpfs on /run failed: Invalid argument
Starting logging: OK
Initializing random number generator... done.
Starting network: ip: socket: Function not implemented
ip: socket: Function not implemented
FAIL
Welcome to MIPSfpga
mipsfpga login:
Работа с GPIO
Воспользуемся возможностями Linux для того, чтобы поуправлять той периферией, которая нам доступна (на момент написания статьи это GPIO, правда не в полном объеме):
проверяем, что драйвер GPIO загружен и устройство доступно:
ls /sys/class/gpio/ export gpiochip480 unexport
для того, чтобы определить доступный диапазон выводов (в текущей конфигурации подключены светодиоды на плате), монтируем debugfs и с ее помощью получаем необходимую информацию:
mount -t debugfs none /sys/kernel/debug cat /sys/kernel/debug/gpio gpiochip0: GPIOs 480-511, parent: platform/bf800000.gpio, bf800000.gpio:
активируем LED0 (в текущем случае это gpio480):
echo 480 > /sys/class/gpio/export
переводим его в режим вывода:
echo out > /sys/class/gpio/gpio480/direction
переводим его в высокий уровень:
echo 1 > /sys/class/gpio/gpio480/value
- если все сделано правильно, то светодиод LED0 должен светиться.
Что дальше
Описанная конфигурация — это, по сути, только начало портирования Linux на систему MIPSfpga-plus. К числу работ, которые необходимо выполнить, чтобы система могла нормально использоваться для практических задач, можно отнести:
- поддержка существующих периферийных устройств: контроллер прерываний, более полная поддержка GPIO, Altera ADC;
- поддержка периферийных устройств MIPSfpga-plus, включая отсутствующие на данный момент PWM, интерфейсы SPI (присутствует ограниченно), I2C, DDR и Ethernet;
- поддержка внешних носителей (mmc/sdram) и возможности загрузки с них;
По этой причине, если в текущей конфигурации вы столкнетесь с какими-то ошибками (багами), то не удивляйтесь — работы еще много.
Благодарности
Автор выражает благодарность коллективу переводчиков учебника Дэвида Харриса и Сары Харрис «Цифровая схемотехника и архитектура компьютера» [L1], компании Imagination Technologies за академическую лицензию на современное процессорное ядро и образовательные материалы, а также персонально Юрию Панчулу YuriPanchul за его работу по популяризации MIPSfpga.
Ссылки
[L1] — Цифровая схемотехника и архитектура компьютера
[L2] — Как начать работать с MIPSfpga;
[L3] — Проект MIPSfpga-plus на github;
[L4] — MIPSfpga и внутрисхемная отладка;
[L5] — MIPSfpga и SDRAM. Часть 1;
[L6] — MIPSfpga и UART;
[L7] — Free Electrons. Free training materials and conference presentations;
[L8] — Free Electrons. Embedded Linux system development course;
[L9] — Free Electrons. Linux kernel and driver development course;
[L10] — Патчи для buildroot и Linux, необходимые для развертывания на MIPSfpga-plus.