Buildroot — часть 2. Создание конфигурации своей платы; применение external tree, rootfs-overlay, post-build скриптов +15


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


Использование EXTERNAL-механизма для кастомизации


В предыдущей статье рассматривался простой пример добавления своей конфигурации, путем добавления defconfig’а платы и нужных файлов непосредственно в каталог Buildroot.


Но этот метод не очень удобен, особенно при обновлении buildroot. Для решения это проблемы есть механизм external tree. Суть его в том, что в отдельном каталоге можно хранить каталоги board,configs,packages и прочие( например, я использую каталог patches для наложения патчей на пакеты, подробнее в отдельном разделе) и buildroot будет сам добавлять их к имеющимися в своем каталоге.


Примечение: можно накладывать сразу несколько external tree, есть пример в руководстве buildroot


Создадим каталог my_tree, находящийся рядом с каталогом buildroot’а и перенесём туда нашу конфигурацию. На выходе должны получить следующую структуру файлов:


[alexey@alexey-pc my_tree]$ tree
.
+-- board
¦   L-- my_x86_board
¦       +-- bef_cr_fs_img.sh
¦       +-- linux.config
¦       +-- rootfs_overlay
¦       L-- users.txt
+-- Config.in
+-- configs
¦   L-- my_x86_board_defconfig
+-- external.desc
+-- external.mk
+-- package
L-- patches

6 directories, 7 files

Как видно, в целом структура повторяет структуру buildroot.


Каталог board содержит файлы, специфичные каждой плате в нашем случае:


  • bef_cr_fs_img.sh — скрипт, который будет выполняться после сборки target-файловой системы, но перед упаковыванием её в образы. В дальнейшем мы его будем использовать
  • linux.config — конфигурация ядра
  • rootfs_overlay — каталог для наложения поверх target-файловой системы
  • users.txt — файл с описанием создаваемых пользователей

Каталог configs содержит defconfig’и наших плат. У нас он всего один.


Package — каталог с нашими пакетами. Изначально buildroot содержит описания и правила сборки ограниченного числа пакетов. Позже мы добавим сюда оконный менеджер icewm и менеджер графического входа в систему Slim.
Patches — позволяет удобно хранить свои патчи для разных пакетов. Подробнее в отдельном разделе далее.
Теперь нужно добавить файлы описания нашего external-tree. За это отвечают 3 файла: external.desc, Config.in, external.mk.


external.desc содержит собственно описание:


[alexey@alexey-pc my_tree]$ cat external.desc 
name: my_tree
desc: My simple external-tree for article

Первая строка — название. В дальнейшем buildroot создать переменную $(BR2_EXTERNAL_MY_TREE_PATH), которую нужно использовать при конфигурировании сборки. Например, путь к файлу с пользователями можно задать следующим путем:


$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/users.txt

Вторая строка — краткое, понятное человеку описание.


Config.in, external.mk — файлы для описания добавляемых пакетов. Если свои пакеты не добавлять, то эти файлы можно оставить пустыми. Пока что мы так и поступим.
Теперь у нас готово наше external-tree, содержащее defconfig нашей платы и нужные ему файлы. Перейдем каталог buildroot, укажем использовать external-tree:


[alexey@alexey-pc buildroot]$ make BR2_EXTERNAL=../my_tree/ my_x86_board_defconfig
#
# configuration written to /home/alexey/dev/article/ramdisk/buildroot/.config
#
[alexey@alexey-pc buildroot]$ make menuconfig

В первой команде мы используем аргумент BR2_EXTERNAL=../my_tree/, указывающий использование external tree.Можно задать одновременно несколько external-tree для использования При этом достаточно сделать это один раз, после чего создается файл output/.br-external.mk, хранящий информацию об используемом external-tree:


[alexey@alexey-pc buildroot]$ cat output/.br-external.mk 
#
# Automatically generated file; DO NOT EDIT.
#

BR2_EXTERNAL ?= /home/alexey/dev/article/ramdisk/my_small_linux/my_tree
BR2_EXTERNAL_NAMES = 
BR2_EXTERNAL_DIRS = 
BR2_EXTERNAL_MKS = 

BR2_EXTERNAL_NAMES += my_tree
BR2_EXTERNAL_DIRS += /home/alexey/dev/article/ramdisk/my_small_linux/my_tree
BR2_EXTERNAL_MKS += /home/alexey/dev/article/ramdisk/my_small_linux/my_tree/external.mk
export BR2_EXTERNAL_my_tree_PATH = /home/alexey/dev/article/ramdisk/my_small_linux/my_tree
export BR2_EXTERNAL_my_tree_DESC = My simple external-tree for article

Важно! В этом файле пути будут абсолютными!


В меню появился пункт External options:



В этом подменю будут содержаться наши пакеты из нашего external-tree. Сейчас этот раздел пустой.


Сейчас нам важнее переписать нужные пути на использование external-tree.


Обратите внимание, что в разделе Build options > Location to save buildroot config, будет абсолютный путь к сохраняемому defconfig'у. Формируется он в момент указания импользования extgernal_tree.


Также в разделе System configuration поправим пути. Для таблицы с создаваемыми пользователями:


$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/users.txt

В разделе Kernel поменяем путь к конфигурации ядра:


$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/linux.config

Теперь при сборке будут использоваться наши файлы из нашего external-tree. При переносе в другой каталог, обновлении buildroot у нас будет минимум проблем.


Добавление root fs overlay:


Данный механизм позволяет легко добавлять/заменять файлы в target-файловой системе.
Если файл есть в root fs overlay, но нет в target, то он будет добавлен
Если файл есть в root fs overlay и в target, то он будет заменён.
Сначала зададим путь к root fs overlay dir. Это делается в разделе System configuration > Root filesystem overlay directories:


$(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/rootfs_overlay/

Теперь проведем создадим два файла.


[alexey@alexey-pc my_small_linux]$ cat my_tree/board/my_x86_board/rootfs_overlay/etc/hosts 
127.0.0.1   localhost
127.0.1.1   my_small_linux
8.8.8.8     google-public-dns-a.google.com.
[alexey@alexey-pc my_small_linux]$ cat my_tree/board/my_x86_board/rootfs_overlay/new_file.txt 
This is new file from overlay

Первый файл (my_tree/board/my_x86_board/rootfs_overlay/etc/hosts) заменит файл /etc/hosts в готовой системе. Второй файл (cat my_tree/board/my_x86_board/rootfs_overlay/new_file.txt) добавится.


Собираем и проверяем:



Выполнение скриптов кастомизации на разных этапах сборки системы


Часто нужно выполнить некоторые действия внутри target-файловой системы до того, как как она будет упакована в образы.


Это можно сделать в разделе System configuration:



Первые два скрипта выполняются после сборки target-файловой системы, но до упаковки её в образы. Разница в том, что fakeroot-скрипт выполняется в контексте fakeroot, те имитируется работа от пользователя root.


Последний скрипт выполняется уже после создания образов системы. В нем можно выполнять дополнительные действия, например, скопировать нужные файлы на nfs-сервер или создать образ своей прошивки устройства.


В качестве примера я создам скрипт, который будет писать версию и дату сборки в /etc/.
Сначала укажу путь к этому файлу в моем external-tree:



А теперь сам скрипт:


[alexey@alexey-pc buildroot]$ cat ../my_tree/board/my_x86_board/bef_cr_fs_img.sh 
#!/bin/sh
echo "my small linux 1.0 pre alpha" > output/target/etc/mysmalllinux-release
date >> output/target/etc/mysmalllinux-release

После сборки можно увидеть этот файл в системе.


На практике, скрипт может стать большим. Поэтому в реальном проекте я пошел более продвинутым путем:


  1. Создал каталог (my_tree/board_my_x86_board/inside_fakeroot_scripts), в котором лежат скрипты для выполнения, с порядковыми номерами. Например, 0001-add-my_small_linux-version.sh, 0002-clear-apache-root-dir.sh
  2. Написал скрипт(my_tree/board_my_x86_board/run_inside_fakeroot.sh), который проходит по этому каталогу и последовательно выполняет скрипты, лежашие в нем
  3. Указал этот скрипт в настройках платы в разеле System configuration -> Custom scripts to run inside the fakeroot environment ($(BR2_EXTERNAL_my_tree_PATH)/board/my_x86_board/run_inside_fakeroot.sh)




К сожалению, не доступен сервер mySQL