Banana Pi: через U-Boot к Arch Linux

Уже четвёртый год подряд, с момента выпуска Raspberry Pi, на рынки всего мира поставляются различные микрокомпьютеры на отличных от x86 архитектурах, которые выполняют роль медиацентров, контроллеров умных домов, веб-серверов и чего только душа гика не пожелает!

К 2014-2015 году не все были довольны вычислительными возможностями «малинки» и начался выпуск десятков его клонов с более мощным железом. У большинства из них есть недостатки: фиксированная устаревшая версия ядра и загрузчика, небольшой выбор дистрибутивов. Под катом расскажу о том, как сбросить оковы вендора на примере Banana Pi.

Предыстория


Во второй половине 2014 года захотелось иметь домашний сервер, выбор встал между классическим на архитектуре x86 с процессором серии Intel Atom и чем-то новым для меня — микрокомпьютером на базе ARM.

После оценки соотношений цены/производительности/возможностей выбор пал на Banana Pi — кроху с двухъядерным Allwinner A20, 1 гигабайтом DDR3, гигабитным LAN'ом, SATA разъёмом и прочими прелестями подобных устройств. Наигравшись пару дней, я смастерил из пластмассовых деталей корпус, в который Banana и была заточена и долго служила для всяких мелких задач.

Дистрибутив стоял Bananian — это Debian 7 Wheezy урезанный во многом для экономии ресурсов. Более нового Debian 8.x нет и по сей день, можете сами представить насколько там старый софт, который получает лишь заплатки безопасности. Всё это безобразие продолжалось до середины лета…



Наконец в июле возникла необходимость поднять веб-сервер и сопутствующие ему сервисы для своего pet project. Пора было сменить старый Debian на что-то менее консервативное и более удобное для меня.

Постановка задачи


К дистрибутиву было поставлено несколько требований: должен «из коробки» иметь репозитории покрывающие все нужды, программы в них должны быть наиболее приближённые к последним доступным версиям. Я слежу за развитием дистрибутивов и входящих в них программ, но при этом ленюсь компилировать всё из сорцов, поэтому очевидным выбором стал Arch Linux.

На сайте производителя в разделе загрузок меня ждал просроченный на год образ с зашитым необновляемым ядром (3.4.100), загрузчиком такой же давности причём от другого устройства (Cubieboard 2). На сайте Arch Linux'а поддержки Banana Pi не было заявлено. Исходя из всего этого оставалось только одно: скомпоновать и запустить дистрибутив самому.

Матчасть




Das U-Boot (происхождение названия как-то связано с субмаринами и игрой слов на немецком и английском языках, см. U-boat)
Это загрузчик операционной системы, ориентированный на устройства c архитектурами MIPS, PowerPC, ARM и другими. Умеет он многое: загружает систему с NAND, NOR, SPI, MMC, SATA, USB, TFTP, NFS, может сам храниться в ПЗУ устройства или внешней памяти, имеет встроенный dhcp клиент и shell, принимает сигналы с клавиатуры, выводит на UART, HDMI, VGA, аналоговое видео. Естественно для поддержки всего этого нужно иметь драйверы.

Тут и начинается отличие от x86 платформ — ARM не имеет ACPI (усовершенствованного интерфейса управления конфигурацией и питанием) и UEFI (интерфейса взаимодействия между операционной системой и «прошивкой» устройства) и именно поэтому не существует как таковых унифицированных дистрибутивов для ARM компьютеров, но движение в сторону UEFI и ACPI идёт уже несколько лет. А пока это движение идёт мы находимся в реальном суровом мире и загрузчик нужно компилировать самостоятельно для разного железа. Железо это описывается в структуре данных под названием Device Tree (dt). Подробнее о DT можно узнать на посвящённом ему сайте: devicetree.org.

В комплекте с исходными кодами загрузчика поставляется набор конфигурационных файлов для компиляции, а также Device Tree для 1089 устройств. Гугл, к сожалению, не находит этот список, поэтому он доступен по ссылке: U-boot supported devices.



Linux Kernel

О нём много писано, много сказано, а сейчас пригодится лишь несколько фактов:
  1. Встреченные мною дистрибутивы хранят ядро в нескольких формах:
    • Image — не сжатый образ.
    • zImage — сжатый самораспаковываяющийся образ.
    • uImage — образ, который имеет обёртку, включающую некоторую информацию для U-Boot'а.

    Ранее uImage использовались обширно для устройств с U-Boot, но за последние года разработчики научили загрузчик работать с zImage, который стал общепринятой практикой хранения образа ядра в дистрибутиве Arch Linux ARM.
  2. Радостная новость! Ядро в пределах одной архитектуры(ARMv5, ARMv6, ARMv7, ARMv8) с большой вероятностью не придётся компилировать для каждого устройства. Оно использует свою версию Device Tree, называемую Device Tree Binary (dtb). Это небольшие по объёму файлы, указывающие ядру какие модули нужно подгружать. Больше информации о dtb можно узнать тут.

От теории к практике


Понадобится:
  • Banana Pi или другой микрокомпьютер из списка поддерживаемых U-Boot'ом устройств
  • Карта памяти и кардридер
  • Компьютер с Linux
  • Установленный тулчейн для нужной архитектуры
    Где взять?
    Наиболее простым способом я считаю следующий:
    1. Скачать готовый тулчейн для своей платформы с сайта Linaro.
      Для Banana Pi нужен linaro-toolchain-binaries (little-endian).
    2. Добавить папку bin тулчейна в PATH:
      export PATH=~/your_toolchain_path/bin/:$PATH



  • Утилиты bc и dtc нужные для компиляции загрузчика, пакеты dosfstools и uboot-tools для создания файловой системы и компиляции скриптов загрузчика, соответственно

Скачаем и распакуем исходные коды последней версии U-Boot:
wget ftp://ftp.denx.de/pub/u-boot/u-boot-latest.tar.bz2
tar -jxf u-boot-latest.tar.bz2

Находим в появившемся каталоге u-boot-2015.07/configs свою «железку» и запоминаем название файла. Для Banana Pi конфигурационный файл называется Bananapi_defconfig.

Ещё помните, что ядро Arch Linux ARM дистрибутиве хранится в zImage? Об этом нужно позаботиться заранее и перед компиляцией добавить возможность загружать самораспаковывающиеся ядра. Точной информации о том уже включено ли это по умолчанию у меня нет, поэтому в каталоге u-boot-2015.07/include/configs/ нужно найти заголовочный файл для платформы Вашего микрокомпьютера (для Banana Pi это sun7i.h) и написать внутри:
#ifndef __CONFIG_H
#define __CONFIG_H
...
#endif /* __CONFIG_H */

строку
#define CONFIG_CMD_BOOTZ

Это добавит возможность использовать в загрузчике команду bootz для запуска самораспаковывающихся сжатых программ.Источник

Теперь этап компиляции. Все операции происходят в каталоге u-boot-2015.07.
А что если без кросс-компиляции?
Если компилируете на той же архитектуре (например, на компьютере с ARMv7), то для make можно опустить флаг CROSS_COMPILE.

make CROSS_COMPILE=arm-linux-gnueabihf- Bananapi_defconfig

Непосредственно компиляция загрузчика:
make CROSS_COMPILE=arm-linux-gnueabihf-

В итоге в нашей рабочей папке должно появиться много файлов с префиксом u-boot. u-boot.bin содержит исполняемый файл загрузчика, но нужен нам файл с постфиксом «with-spl». SPL — небольшая программа, которая располагается непосредственно перед загрузчиком и загружает сам U-Boot в оперативную память. Для Banana Pi это файл u-boot-sunxi-with-spl.bin. Сохраним его, он пригодится чуть позже.

Следующий шаг — подготовка флеш-карты с которой будет загружаться система. Как должна выглядеть её разметка:



Подключим флеш-карту через кард-ридер и запустим утилиту fdisk:
fdisk /dev/sdb

Как узнать какое имя у Вашей карты?
В каталоге /dev/ должен появиться новый файл, соответствующий вставленной карте. Она определится либо как SCSI-устройство (sda, sdb, sdc...), либо как блочная MMC память (mmcblk0, mmcblk1 ...).

Добавим MBR разметку:
Command (m for help): o
Created a new DOS disklabel with disk identifier 0xa53166ce.

И обязательно как минимум два раздела:
  1. 50-100 Мб
    fdisk, разметка первого
    Command (m for help): n   
           Partition type
              p   primary (0 primary, 0 extended, 4 free)
              e   extended (container for logical partitions)
           Select (default p): p
           Partition number (1-4, default 1): 1
           First sector (2048-7831551, default 2048): 2048
           Last sector, +sectors or +size{K,M,G,T,P} (2048-7831551, default 7831551): +75M
    
           Created a new partition 1 of type 'Linux' and of size 75 MiB.
           


  2. 2 Гб и более
    fdisk, разметка второго
    Command (m for help): n
           Partition type
              p   primary (1 primary, 0 extended, 3 free)
              e   extended (container for logical partitions)
           Select (default p): p
           Partition number (2-4, default 2): 2
           First sector (155648-7831551, default 155648): 155648
           Last sector, +sectors or +size{K,M,G,T,P} (155648-7831551, default 7831551): +3G
    
           Created a new partition 2 of type 'Linux' and of size 3 GiB.
    



После всего этого ввести «w», тем самым записать изменения на диск.

Почему именно такие разделы? U-Boot'ом можно управлять с помощью скриптов, он читает их только из первого раздела накопителя, причём раздел этот должен быть с файловой системой FAT. В этот же раздел будет смонтирован каталог /boot будущего Arch Linux'а для удобного доступа к ядрам как из U-Boot скриптов, так и для быстрой подмены ядер с любого попавшегося компьютера. Второй раздел предназначен для корня системы. Остальные по желанию.

После разметки нужно очистить место для загрузчика. Крайне важно не затереть первые 512 байт(MBR) и не затронуть 1024 секторы и далее (исходя из таблицы выше):
dd if=/dev/zero of=/dev/sdb bs=1K count=1023 seek=1

Запишем U-Boot:
dd if=u-boot-sunxi-with-spl.bin of=/dev/sdb bs=1024 seek=8

Теперь уже можно вставить флешку в устройство назначения, включить его и посмотреть как оно весело мигает LED'ами, подхватывает ip-адрес через dhcp, пытается достучаться до tftp сервера чтобы загрузиться и дружелюбно приглашает Вас в свой Shell показывая его через выдеовыход или UART.

Но одного загрузчика мало, остаётся ещё несколько компонентов: скрипт для управления U-Boot'ом и сам дистрибутив Arch Linux.
Отправляемся на os.archlinuxarm.org и скачиваем архив с подходящим нашей архитектуре дистрибутивом. Для Banana это ArchLinuxARM-armv7-latest.tar.gz. Распаковываем в отдельную директорию и продолжаем манипуляции с флеш-картой.

Создадим файловые системы и примонтируем их в заданном порядке:
mkfs.vfat /dev/sdb1
mkfs.ext4 /dev/sdb2
mount /dev/sdb2 /mnt
mkdir /mnt/boot
mount /dev/sdb1 /mnt/boot

Скопируем всё содержимое распакованного архива в /mnt:
cp -r ~/ArchLinux-generic-armv7/* /mnt

Заглянем в первый раздел флешки (/mnt/boot). Внутри нас ждёт папка dtbs и сжатый образ ядра — zImage. dtbs — это именно те Device Tree Binary, о которых шла речь выше.
Для ARMv7 есть целых 301 dtb. Список можно увидеть здесь или непосредственно открыв директорию boot/dtbs дистрибутива на своём компьютере. Если dtb есть, то ядро заведётся с почти 100% вероятностью. Для Banana Pi нужный файл — sun7i-a20-bananapi.dtb. Он нужен нам для последнего и завершающего этапа — написания скрипта для U-Boot'а и, естественно, запуска всей полученной системы.

Приступим. Создадим прямо на месте (в /mnt/boot) файл boot.cmd и начнём писать.

Первым делом прикажем U-Boot'у загружать в RAM образ ядра:
fatload mmc 0 0x46000000 zImage

Затем dtb для нужного девайса:
fatload mmc 0 0x49000000 dtbs/sun7i-a20-bananapi.dtb

Установим параметры для запуска ядра:
setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rw rootwait panic=10

И скажем ему загружаться из этой области памяти, тем самым передавая управление уже ядру Linux.
bootz 0x46000000 - 0x49000000

Области памяти доступные для загрузки у каждой модели свои и к сожалению я не знаю как определять их самостоятельно. Буду очень рад, если кто-то расскажет об этом простыми словами в комментариях.

Написанный нами скрипт остаётся только скомпилировать. Для этого в пакете uboot-tools есть утилита mkimage, воспользуемся ей:
mkimage -C none -A arm -T script -d boot.cmd boot.scr

boot.cmd при желании можно удалить, загрузчику нужен лишь boot.scr.
А бывает ещё что-то вроде boot.scr?
Да, бывает. U-Boot для некоторых устройств можно сконфигурировать через простой текстовый файл uEnv.txt, это зависит от вендора, но с Banana Pi такой трюк не прокатит.

И последний штрих — добавляем в etc/fstab новой системы разделы, которые будут подключаться при запуске:
/dev/mmcblk0p2    /    ext4    rw,relatime,data=ordered 0 1
/dev/mmcblk0p1 /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2

Флешку можно вставлять в девайс и радоваться свежей системе. Демон dhcpd сам подхватит адрес если в Вашей сети есть DHCP сервер. SSH сервер по умолчанию добавлен в автозагрузку. Аккаунт на дефолтных образах Arch Linux ARM изначально всегда один: root/root. Обязательно смените пароль и добавьте юзера с ограниченными полномочиями.



Итог


Что получили? Звёзды так сошлись, что поддержка моего микрокомпьютера есть в списке из 1089 устройств поддерживаемых U-Boot и среди 301-го среди поддерживаемых mainline ядром для ARMv7. Поэтому получили именно то, что и хотели: систему с самым свежим программым обеспечением, которое стабильно обновляется из репозиториев, включая ядро системы (на данный момент уже 4.1.4). Стабильная ветка загрузчика обновляется раз в 3 месяца и требуется лишь скомпилировать его и повторить процедуру установки, как сделано выше.

Что не работает "out of the box"?
В составе ядра и дистрибутиве нет ни ядерной, ни userspace частей драйвера Mali. Это обусловлено тем, что полнофункциональный билд возможен только с помощью проприетарного SDK, который предоставляется только партнёрам компании ARM.

Для ленивых


Подготовил образ для Banana Pi:
Ссылка, Зеркало #1, Зеркало #2.
md5 образа в архиве: f36d707c4c1fd857b50d37501b4a3d7a
Записать образ на флеш-карту можно с помощью утилиты dd, либо win32diskimager (для Windows пользователей).

Источники


linux-sunxi.org/Mainline_U-boot
elinux.org/RPi_Hub
ru.wikipedia.org/wiki/Das_U-Boot

Желаю удачи тем, кто захочет повторить это у себя дома и буду рад справедливой критике.

Share post

Comments 24

    +1
    > Дистрибутив стоял Bananian — это Debian 7 Wheezy урезанный во многом для экономии ресурсов. Более нового Debian 8.x нет и по сей день, можете сами представить насколько там старый софт, который получает лишь заплатки безопасности.

    Работа по установке арча конечно титаническая, но имхо несколько излишняя)

    Bananian использует ARM репозитории Debian, можно было просто переключиться на более новый репозиторий вместо смены дистрибутива.
    Плюс, в арче не факт что присутствуют все те оптимизации под конкретно BananaPi, которые есть в Bananian.

    За себя скажу, что у самого домашний сервер на Banana Pi + Bananian, и пока на нём не возникало задач, требующих прям уж свежайшего софта. NFS, TFTP, апач какие-то из wheezy стоят и ладно.
      0
      И правда, можно было обойтись Testing репозиториями в Debian и даже какое-то время я их использовал, но юношеский максимализм победил :) Да и плотно засел изучать systemd, а Bananian никак не хотел обновлять его ссылаясь на низкую версию ядра.
        0
        С опытом и возрастом это проходит. Как-то понимаешь, что нет разницы сколько лет назад выпустили этот софт, если он просто выполняет ту задачу, которая тебе нужна.
      0
      Большое, человеческое спасибо, за столь подробное описание сборки и настройки именно uBoot.
      Арчем не пользуюсь, но уже два года пользую очень похожую на вашу платку — cubieboard2. там такой же SoC и похожая обвязка.
      Сейчас использую ее как dev сервер для веба, под убунтой.
      Долгое время она жила у меня под gentoo (вот где пришлось пошаманить, чтобы собрать ее на самой плате), но с ядрами была печаль — гентушные ядра из ветки armhf работать не хотели ни в какую, поэтому приходилось использовать весьма старые ядра от linux-sunxi, подкладывать их вручную.

      P.S. после прочтения статьи, снова почувствовал зуд в ладонях :) видимо пора впилить на платку что нибудь новое… пойду про alpinelinux почитаю, его многие хвалят :)
        +1
        Рад что вдохновил вас!) Если что — у cubieboard2 есть мэйнтейнер в рядах разработчиков Arch Linux ARM и дистрибутив для Вашей платы подготовлен, всегда свежий загрузчик лежит прямо в репозиториях в пакете uboot-cubieboard2.
          0
          Спасибо, буду иметь ввиду. Просто Arch никогда не попадал в сферу моих интересов.
          рабочее место под ubuntu серваки под centos а вот всякие малыши — это повод почесать ладони и покрасноглазить :)

          у cubieboard2 есть мэйнтейнер в рядах разработчиков Arch
          а вот это действительно удивительно, потому что ни в одном другом дистрибутиве я такого не встречал.

          P.S. Кстати в ряду «пи» плат есть еще «orange pi» которые в версии 2 и в версии plus собраны на четырехъядерном Allwinner H3 и цена при этом в пределах полтинника.
          0
          Может пригодится kernelci.org/boot
          Видос про них. Постоянно тестируют под многие платы.
            0
            Долгое время она жила у меня под gentoo (вот где пришлось пошаманить, чтобы собрать ее на самой плате)


            Да вы извращенец батенька. Все можно собирать на хосте, а затем просто копировать на таргет. Может будет полезно если захотите вернуться на gentoo.

            Я сейчас пилю тулчейны основанные на gentoo, правда они больше связаны с openautomotive, возможно дойдут руки и сделаю вариант для сборки серверов.
              0
              Да вы извращенец батенька. Все можно собирать на хосте, а затем просто копировать на таргет.


              Скажу честно, ядра я преимущественно собирал на хосте под убунтой. (20 минут против 3,5 часов на кубике),
              а вот саму систему пробовал и так и эдак.
              У меня вообще совпало знакомство с gentoo и знакомство с платой :)
              а gentoo привлекла меня возможностью тонкого тюнинга при сборке софта, очень хотелось выжать лишние проценты производительности в условиях ограниченной мощности железки.
                0
                Тут есть подводный камень, весь софт в gentoo заточен под x86 платформы, потому для ARM зачастую приходится переписывать ebuild'ы и включать всевозможные arm специфичные фичи от разработчиков самих программ. Например использование neon, openGLES и т.п.
                  0
                  то есть доверять ветке arm или arm~ из основного репозитория нельзя?
                    0
                    Не то чтобы доверять, но зачастую они мало чем отличаются от своих десктопных братьев несмотряю на наличие оптимизаций заложенных в процедуру сборки мейнтенерами самих приложений. Я не отговариваю вас пользоваться :) Но обращайте внимание на флаги оптимизации которые заложили мейнтейнеры.
            0
            Bananian 15.08 на основе Debian Jessie в августе — www.bananian.org/news#bananian_1508_release_at_froscon_10_-_2015-07-14
            А обновляться уже сейчас можно, но я не стал что-то )

            В любом случае, статья интересная. Очень мало инфы по этой неплохой плате.
              0
              Вот это заявление не совсем верное:
              Для ARMv7 есть целых 301 dtb. Список можно увидеть здесь или непосредственно открыв директорию boot/dtbs дистрибутива на своём компьютере. Если dtb есть, то ядро заведётся с почти 100% вероятностью. Для Banana Pi нужный файл — sun7i-a20-bananapi.dtb

              Заведенное ядро не дает кучи драйверов, которые в процессе портирования на mainline.

              Ну и самое главное — графическая подсистема не заведена. Я сейчас озадачен этой проблемой. ARM расшарили исходники low-level драйверов для Mali 400/450 в т.ч. UMP, но openGL/GLES все еще закрыты(да и никогда не будут раскрыты). Надо как-то заставить Allwinner пошевелиться и предоставить бинарники openGL/ES,ELG,openVG для X11 и EGL. То что пошарил ARM непригодно текущих библиотек, которые лежат в репозиториях Allwinner.

                0
                Спасибо за комментарий, упомянул о проблеме графической системы в спойлере «Что не работает „out of the box“?». Пока что я не нашёл очевидных решений, разве что написать команде sunxi, открыть у них тикет на гитхабе? Может там дадут хоть какой-то ответ. Не нравится мне политика ARM по отношению к опенсорсу, вроде код то и открыт, а воспользоваться им полноценно нельзя.
                  0
                  Спойлер работает :) И я его прочел, просто решил развить тему. Так вот по поводу политики ARM там на сайте английским по белому написано:
                  Note that these components are not a complete driver stack. To build a functional OpenGL ES or OpenVG driver you need access to the full source code of the Mali GPU DDK, which is provided under the standard ARM commercial licence to all Mali GPU customers. For a complete integration of the Mali GPU DDK with the X11 environment refer to the Integration Guide supplied with the Mali GPU DDK.


                  Команда sunxi не сможет ничего сделать. Нужно чтобы пошевелился сам Allwinner поскольку он-то как раз и является «all Mali GPU customers». А openGL стэк доступный на сайте работает только с версиями low-level драйверов для ядер < 3.4. Такие вот неутешительные моменты. На днях сочиню письмо в службу поддержки Allwinner и попробую выбить у них новые библиотеки. Потому что low-level драйверы вполне себе живут по соседству с 4.x ядрами linux. Само собою работоспособность проверить не удалось :)
                0
                Выбор ARM плат действительно велик, но есть ли среди них хоть одна поддерживающая в Linux аппаратное видеоускорение?
                  0
                  Конечно есть, VideoCore IV в Raspberry Pi всех ревизий поддерживает такую фичу. Очень много устройств сделано на базе Allwinner/Exynos и во всех применяется довольно проблемное(для энтузиастов) видео Mali, но насколько я знаю вендоры вроде ODROID, LeMaker поставляют дистрибутивы, в которых полностью рабочий графический стек, но естественно он зашит и не обновляется.
                    0
                    Наилучший вариант в плане поддержки сейчас у i.mx6-based плат от freescale. Там поддержка вполне себе живая, особенно linux.
                    Но цена по сравнению с Cubieboard, Raspberry Pi, Banana Pi и др. кусается. Есть еще куча недостатков, но основная для энтузиастов — цена.
                    0
                    Записал ваш образ на карту памяти, но он не загружается. В чём может быть проблема?
                    U-Boot 2014.04-10733-gbb5691c (Dec 18 2014 - 12:58:21) Allwinner Technology     
                                                                                                    
                    CPU:   Allwinner A20 (SUN7I)                                                    
                    Board: BananaPi                                                                 
                    I2C:   ready                                                                    
                    DRAM:  1 GiB                                                                    
                    MMC:   SUNXI SD/MMC: 0                                                          
                    *** Warning - bad CRC, using default environment                                
                                                                                                    
                    In:    serial                                                                   
                    Out:   serial                                                                   
                    Err:   serial                                                                   
                    Net:   
                    

                    после этого плата выключается
                      0
                      Здравствуйте! Контрольные суммы сверяли? Если всё верно, то проблема вероятно с картой памяти или заливанием образа на неё. Отформатируйте её полностью через Low level format tool(Windows) или через dd забейте нулями из /dev/zero с размером сектора по 512КБ. Затем попробуйте либо с помощью dd, либо Win32diskimager записать образ с точно совпадающим MD5.
                      У меня под рукой была ещё одна банана неделю назад, на неё удачно встал мой образ.
                        0
                        Пардон, проблема с питанием: когда поднималась сетевуха — всё падало. Называется, привык, что аппаратных проблем нет)
                          0
                          Всяко бывает :) знакомые умудрялись и питание в OTG запихивать. Странно что при этом банана подавала признаки жизни.
                      0
                      Замечательная статья. Хочу на её основе сделать образ для Orange Pi PC. Только вот у вас ссылка на Device Tree не работает. Где можно взять Device Tree?

                      Only users with full accounts can post comments. Log in, please.