[Из песочницы] Buildroot — часть 1. Общие сведения, сборка минимальной системы, настройка через меню

Введение

В данной серии статей я хочу рассмотреть систему сборки дистрибутива buildroot и поделиться опытом её кастомизации. Здесь будет практический опыт создания небольшой ОС с графическим интерфейсом и минимальным функционалом.

Прежде всего, не следует путать систему сборки и дистрибутив. Buildroot может собрать систему из набора пакетов, которые ему предложили. Buildroot построен на make-файлах и поэтому имеет огромные возможности по кастомизации. Заменить пакет на другую версию, добавить свой пакет, поменять правила сборки пакета, кастомизировать файловую систему после установки всех пакетов? Всё это умеет buildroot.

В России buildroot используется, но на мой взгляд мало русскоязычной информации для новичков.

Цель работы — собрать дистрибутив с live-загрузкой, интерфейсом icewm и браузером. Целевая платформа — virtualbox.

Зачем собирать свой дистрибутив? Зачастую нужен ограниченный функционал при ограниченных ресурсах. Ещё чаще в автоматизации нужно создавать прошивки. Приспосабливать дистрибутив общего назначения, вычищая лишние пакеты и превращать его в прошивку путь более трудоёмкий, чем собрать новый дистриб. Использование Gentoo тоже имеет свои ограничения.

Buildroot система очень мощная, но она ничего не сделает за вас. Она может лишь дать возможности и автоматизировать процесс сборки.

Альтернативные системы сборки (yocto, open build system и прочие) не рассматриваются и не сравниваются.


Где взять и как начать

Сайт проекта — buildroot.org. Здесь можно скачать актуальную версию и прочитать руководство. Там же можно обратиться к сообществу, есть багтрекер, mail-lists и irc-канал.

Buildroot оперирует defconfig«aми для целевой платы сборки. Defconfig — это конфигурационный файл, хранящий в себе только опции, не имеющими значения по умолчанию. Именно он определяет, что и как будет собрано. При этом можно отдельно настроить конфиги busybox, linux-kernel, uClibc, загрузчиков u-boot и barebox, но все они будут привязаны к целевой плате.
После распаковки скачанного архива или клонировании из git получаем готовый к работе buildroot. Подробно о структуре каталогов можно прочитать в руководстве, расскажу о самых важных:

board — каталог с файлами, специфичными для каждой платы. Это могут быть скрипты формирования образов системы (iso, sdcart, cpio и прочие), каталог overlay, конфиг ядер и прочее
configs — собственно defconfig платы. Defconfig — это неполная конфигурация платы. В нем хранится только отличные от дефолтных настроек параметры
dl — каталог со скачанными исходными кодами/файлами для сборки
output/target  — собранная файловая система полученной ОС. В дальнейшем из нее создаются образы для загрузки/установки
output/host  — host-утилиты для сборки
output/build  — собранные пакеты

Конфигурирование сборки осуществляется через KConfig. Эта же система используется для сборки ядра linux. Список самых часто используемых команд (выполнять в каталоге buildroot):


  • make menuconfig — вызвать настройку сборки. Так же можно с использование графического интерфейса (make nconfig, make xconfig, make gconfig)
  • make linux-menuconfig — вызвать конфигурацию ядра.
  • make clean — очистить результаты сборки (всё что храниться в output)
  • make — собрать систему. При этом не выполняется пересборка уже собранных процессов
  • make defconfig_name — переключить конфигурацию на определенный defconfig
  • make list-defconfigs — показать список defconfig«ов
  • make source — только скачать установочный файлы, без сборки.
  • make help — вывести список возможных команд


Важные замечания и полезные советы

Buildroot не пересобирает уже собранные пакеты! Поэтому может создаться ситуация, когда потребуется полная пересборка.

Можно пересобрать отдельный пакет командой make packagename-rebuild. Например, можно пересобрать ядро linux:

make linux-rebuild

Buildroot хранит состояние любого пакета созданием .stamp-файлов в каталоге output/build/$packagename:

usiuf3l_-ics3e8gdbnzebjszzs.png

Следовательно, можно пересобрать root-fs и образы без пересборки пакетов:

rm output/build/host-gcc-final-*/.stamp_host_installed;rm -rf output/target;find output/ -name ".stamp_target_installed" |xargs rm -rf ; make


Полезные переменные

В buildroot есть набор переменных для удобного конфигурирования


  • $TOPDIR — корневой каталог buildroot
  • $BASEDIR — каталог OUTPUT
  • $HOST_DIR, $STAGING_DIR, $TARGET_DIR — каталоги сборки host fs, staging fs, target fs.
  • $BUILD_DIR — каталог c распакованными и собранными пакетами


Визуализация

В buildroot есть возможность по визуализации.Можно построить схему зависимостей, график времени сборки, график размера пакетов в итоговой системе. Результаты в виде pdf файлов (на выбор есть svn, png) в каталоге output/graph.

Примеры команд визуализации:


  • make graph-depends построить дерево зависимостей
  • make -graph-depends построить дерево зависимостей конкретного пакета
  • BR2_GRAPH_OUT=png make graph-build построить график времени сборки с выводом в PNG
  • make graph-size построить график размера пакетов


Полезные скрипты

В каталоге buildroot есть подкаталог utils c полезными скриптами. Например, там есть скрипт, проверяющий корректность описания пакетов. Это может быть полезно при добавлении своих пакетов (я это сделаю позже). В файле utils/readme.txt есть описание этих скриптов.


Соберем cтоковый дистрибутив

Важно напомнить, что все операции ведутся от лица обычного пользователя, не root.
Все команды выполняются в корне buildroot. В поставке buildroot уже есть набор конфигураций под многие распространённые платы и виртуализацию.

Смотрим список конфигураций:

usiuf3l_-ics3e8gdbnzebjszzs.png

Переключаемся на конфиг qemu_x86_64_defconfig

make qemu_x86_64_defconfig

И запускаем сборку

make

Сборка завершается успешно, смотрим на результаты:

pb2vsbi3oe_repbvq6f0bkqf7ee.png

Buildroot собрал образы, которые можно запустить в Qemu и убедиться, что они работают.

qemu-system-x86_64 -kernel output/images/bzImage -hda \   output/images/rootfs.ext2 -append "root=/dev/sda rw" -s -S

Результат — запущенная в qemu система:

wzm7uardoe4pbefa1ni8fij4pui.png


Создание конфигурации собственной платы


Добавление файлов платы

Смотрим список конфигураций:

omemsxpgtlfovmawbojohn5ma_a.png

В списке видим pc_x86_64_efi_defconfig. Мы создадим свою плату, скопировав её с конфигурации:

cp configs/pc_x86_64_bios_defconfig configs/my_x86_board_defconfig

Сразу же создадим каталог платы для хранения своих скриптов, rootfs-overlay и прочих нужных файлов:

mkdir board/my_x86_board

Переключаемся на этот defconfig:

make my_x86_board_defconfig

Таким образом, теперь конфиг сборки (хранится в .config в корне каталога buildroot«а) соответствует целевой машине x86–64 legacy (bios) загрузкой.

Скопируем конфигурацию linux-kernel (пригодится в дальнейшем):

cp board/pc/linux.config board/my_x86_board/


Настройка параметров сборки через KConfig

Запускаем настройку:

make menuconfig 

Откроется окно KConfig. Есть возможность конфигурировать с графическим интерфейсом (make nconfig, make xconfig, make gconfig):

ai6dub6beukqket6qcz3ezc9c5i.png

Входим в первый раздел Target Options. Здесь можно выбрать целевую архитектуру, под которую будет вестись сборка.

pujlv2tlusbnnenf9gstmsosyf4.png

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

Toolchain — здесь настраивается сам инструментарий сборки. О нем подробнее.

mb-egyihomze0cx9vriprqph1ly.png

Toolchain type — тип используемого тулчейна. Это может быть встроенный в buildroot или внешний тулчейн (можно указать каталог с уже собранным или url для скачивания). Для разных архитектур есть дополнительные опции. Например, для arm можно просто выбрать версию внешнего тулчейна Linaro.

C library — выбор библиотеки С. От этого зависит работа всей системы. Обычно используется glibc, поддерживающая весь возможный функционал. Но она может оказаться слишком большой для встроенной системы, поэтому часто выбирают uClibc или musl. Мы выберем glibc (в дальнейшем это потребуется для использования systemd).

Kernel Headers и Custom Kernel Headers series — должно совпадать с версией ядра, которое будет в собираемой системе. Для kernel headers можно так же указать путь к тарболу или git-репозиторий.

GCC COMPILER VERSIONS — выбор версии компилятора, которая будет использована для сборки
Enable C++ support — выберем для сборки с поддержкой библиотек c++ в системе. В дальнейшем нам это пригодится.

Additional gcc options — можно задать дополнительные опции компилятора. Нам без надобности пока что.

System configuration позволяет задать будущие параметры созданной системы:

3ykkfukfm4ptl2iiiqs2bhvbn_0.png

Большинство пунктов понятны из названия. Обратим внимание на следующие пункты:
Path to the users tables — таблица с создаваемыми пользователями (https://buildroot.org/downloads/manual/manual.html#makeuser-syntax).

Пример файла. Будет создан пользователь user с паролем admin, автоматически gid/uid, /bin/sh шеллом, группой по-умолчанию user, член группы root, комментарием Foo user

[alexey@alexey-pc buildroot ]$ cat board/my_x86_board/users.txt 
user -1 user -1 =admin /home/user /bin/sh root Foo user

Root filesystem overlay directories — каталог, накладываемый поверх собранной target-fs. Добавляет новые файлы и заменяет имеющиеся.

Custom scripts to run before creating filesystem images — Скрипты, выполняемые непосредственно перед сворачиванием файловой системы в образы. Сам скрипт пока оставим пустым

Перейдём в раздел Kernel

_u-micbjjhq3dg_hoawyozkkqgk.png

Здесь задаются настройки ядра. Само ядро конфигурируется через make linux-menuconfig.
Задать версию ядра можно по-разному: выбрать из предложенных, ввести версию вручную, указать репозиторий или готовый tarball.

Kernel configuration — путь к конфигу ядра. Можно выбрать конфигурацию по-умолчанию для выбранной архитектуры или defocnfig из Linux. В исходниках Linux есть набор defconfig«ов для разных целевых систем. НАйти нужный можно, глянув напрямую в исходники здесь. Например, для платы beagle bone black можно выбрать конфиг.

Раздел Target packages позволяет выбрать, какие пакеты будут установлены в собираемую систему. Пока оставим без изменений. Позже мы добавим свои пакеты в этот список.
Filesystem images — список образов файловых систем, которые будут собраны. Добавим iso-образ

negzo-lbw2ci9i-hnj7pzg9tm88.png

Bootloaders — выбор собираемых загрузчиков. Выберем isolinix

axnbqyxbxffyyyqz7qgle5ectgu.png


Конфигурирование Systemd

Systemd становится одним из столбов linux, наравне с kernel и glibc. Поэтому вынес его настройку в отдельный пункт.

Настраивается через make menuconfig, далее Target packages → System tools → systemd. Здесь можно указать, какие службы systemd будут установлены и запущены при старте системы.

_3nkskizxu-lxd5pvq4fr9dqn5c.png


Сохранение конфигурации системы

Сохраняем этот конфиг через KConfig.

После чего сохраним наш defconfig:

make savedefconfig


Конфигурирование ядра Linux

Конфигурирование ядра linux вызывается следующей командой:

make linux-menuconfig

Добавим поддержку видеокарты Virtualbox

xgtx2xqc52qpvqhzhpojpk3tebs.png

Добавим Virtualbox Guest integration support

xgtx2xqc52qpvqhzhpojpk3tebs.png

Сохраняем и выходим. ВАЖНО: конфигурация сохранится в output/build/linux-$version/config, но не в board/my_x86_board/linux.config

wpqydmxqz1j3ttq_5vcom1uv38q.png

Поэтому нужно вручную скопировать конфиг в место хранения:

cp output/build/linux-4.19.25/.config board/my_x86_board/linux.config

После чего выполним полную пересборку всей системы.Т.к. buildroot не пересобирает уже собранное, то надо вручную указать пакеты для пересборки. Чтобы не терять время и нервы, небольшую систему проще пересобрать целиком):

make clean;make

По завершении сборки запускаем VirtualBox (проверялось на версии 5.2 и 6.0) с загрузкой с cd-диска.Параметры системы:

mi_-pb0m79dbqf1tpg8x72hk9vk.png

Запуск с собранного iso:

aiuquwkxe2-ac9hom0h5vdpnjve.png


Список использованных материалов


  1. Buildroot manual

© Habrahabr.ru