Все это собиралось из под Ubuntu 16.04.
Решение собрать прошивку родилось из за отсутствия в свободном доступе образа для этой платы (Olimex A13-Olinuxino). А производитель предлагал преобрести SD карту с образом и стоило что то около 10 евро на тот момент, что очень не устроило, к тому же она была рассчитана на наличие монитора.
Конфигурирование загрузчика будем формировать для загрузки с SD карты. Поскольку NAND памяти на плате нету а все остальные варианты загрузки слегка кривоваты (у кого получиться собрать uboot для загрузки с USB носителя, пусть сделает два шага вперед и поделится). Алгоритм загрузки процессора allwinner a13 можно найти на сайте производителя. Или вот вырезка из даташита.
Из алгоритма хорошо видно что сначала идет проверка загрузчика на SD карте, потом все остальные и только в конце проверяется наличие загрузчика на USB. Поэтому планшеты и смартфоны вполне можно сделать с Ubuntu если им подсунуть SD карту с соответствующим образом. И судя по всему примерно такой алгоритм будет если не у всех, то у многих производителей arm процессоров.
Для начала нужно разбить SD карту, для этого дабы не ошибится в процессе набора комманд, сведем весь процесс в файл скрипта (я предпочитаю все сводить к таким файлам, так как запускать его придется не раз).
#!/bin/sh
DEViCELINK=/dev/sdb
fdisk $DEViCELINK <<EOF
n # создать новый раздел
p # печать раздела
1 # номер раздела
2048 # создать раздел с отступом 2MiB
+64M # размер раздела, тут будет лежать kernel файл с переменными и dts файл
n
p
2
+2G # этот раздел для ubuntu
n
p
3
+2G # этот в дальнейшем станет для каскадной файловой системы
n
p
4 # а в этом разделе будет весь остальной размер
w
EOF
mkfs.ext2 /dev/sdb1 << EOF # раздел с kernell должен быть либо fat16 либо ext2
y
EOF
mkfs.ext4 /dev/sdb2 << EOF
y
EOF
mkfs.ext4 /dev/sdb3 << EOF
y
EOF
mkfs.ext4 /dev/sdb4 << EOF
y
EOF
Сборка UBOOT
Остановимся по подробней на загрузчике, а в качестве оного выбираем UBOOT выкачиваем версию u-boot-2018.05, последнюю на тот момент.
Предполагается что уже стоит весь необходимый софт для сборки. И начнем сборку с конфигурирования загрузчика.
Для запуска конфигурирования необходимо зайти в папку с UBOOT и из неё выполнить команду:
make O=../olimex-uboot # адрес где будет лежать результат сборки
-j4 # количество потоков для сборки
ARCH=arm # тип архитектуры для которой собирается
CROSS_COMPILE=arm-linux-gnueabihf- # кроскомпилятор нашего процессора
xconfig # команда запуска GUI конфигуратора
В результате выполнения получим такое окно.
Это так называемый иксовый вариант конфигуратора, обычно пользуются вариантом консольным в нём больше информации предоставлено, но в этом всё более наглядней и он вполне покроет наши потребности.
А дальше если у вас много времени или вам себя не жалко, можно самим с нуля сконфигурировать загрузчик. Однако лучше через меню файл загрузить готовую конфигурацию этой платы. В папке с исходником загрузчика по адресу /u-boot-2018.05/configs/ выбираем файл A13-OlinuXino_defconfig это и есть наша конфигурация, где все уже установлено. Дальше нажимаем сохранить и закрываем окно, ибо менять тут ничего не нужно.
Остаётся запустить команду сборки:
make O=../olimex-uboot
-j4
ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
В этой команде элементы все те же самые что и в предыдущей, только без параметра xconfig, что и означает конфигурирование. Вот собственно и все, загрузчик собран.
После окончания сборки, в папке указанной в команде, нам нужно найти этот файл “u-boot-sunxi-with-spl.bin” это и есть нужный загрузчик.
Дальше для заливки загрузчика на SD карту воспользуемся командой:
dd if=../olimex-uboot/u-boot-sunxi-with-spl.bin # откуда брать файл для загрузки
of=/dev/sdb # загружаем в самое начало SD карты
bs=1024 seek=8 # отступаем 8KiB от начала, отсюда будет записано начало загрузчика
Загрузчик что только что записали после загрузки укажет на следующий раздел SD карты /dev/sdb1, и там будет искать скрипт файл с переменными окружения в котором содержаться инструкции по дальнейшей загрузке.
Этот файл должен иметь имя boot.scr, файл с этим названием ищет uboot после своей загрузки. Название файла конечно можно изменить как и метод загрузки если влезть в конфигурацию UBOOT, но остановимся на этом варианте.
Также следует за одно скомпилировать devicetree файлы, они лежат в исходниках с загрузчиком по адресу /u-boot-2018.05/arch/arm/dts/ нас интересует файл sun5i-a13-olinuxino.dts. Он представляет собой конфигруацию регистров и переферии процессора. Этакий универсальный файл конфигурации, поэтому вполне возможен вариант когда один загрузчик uboot используется для разных процессоров но при этом используются разные файлы dts. Такие же файлы dts есть и в исходниках ядра линукса, они в принципе одинаковы только написанны немного по разному и откуда брать собранное дерево устройств это уже выбирать вам. В общем для сборки dts файлов нужно запустить эту команду:
make O=../olimex-uboot
-j4
ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
dtbs # опция указывающая что необходимо собрать dts файлы
Скомпилированный файл будет лежать по адресу ../olimex-uboot/arch/arm/dts/.
Рассмотрим подробней получение файла boot.scr.
Для начала создадим файл boot.cmd с содержимым:
load mmc 0 0x43000000 sun5i-a13-olinuxino.dtb
load mmc 0 0x42000000 uImage
setenv bootargs root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait console=ttyS0,115200
bootm 0x42000000 – 0x43000000
Но для того чтоб uboot понял инструкции, этот файл должен быть в виде скрипта и для этого нужно запустить команду:
mkimage -C none -A arm -T script -d boot.cmd boot.scr
Где boot.scr необходимый файл.
Первая строка load mmc 0 0x43000000 sun5i-a13-olinuxino.dtb загружает файл дерева устройств по указанному адресу в оперативной памяти. load mmc 0 указывает что загружать нужно файл с первого раздела SD карты, при этом нумерация для uboot происходит нуля а не единицы.
Вторая строка load mmc 0 0x42000000 uImage загружает по указанному адресу собранное ядро линукса.
Для нашего варианта переменная setenv video-mode которая обычно дальше используется, нам не нужна так как монитор использовать не планируется.
Третья строка:
setenv bootargs # объявляет агрументы загрузки
root=/dev/mmcblk0p2 # указатель на раздел SD карты где размещен rootfs
rootfstype=ext4 # тип файловой системы rootfs
rw # перезаписываемая файловая система
rootwait
console=ttyS0,115200 # порт для консоли uart0
Ну и последняя команда bootm загружает ядро с раннее загруженного в памяти.
В следующей статье будет последняя часть что должна размещаться на первом разделе SD карты, это формирование ядра линукса kernell.
Автор: dombran