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

В данном разделе я рассматриваю часть возможностей по кастомизации, которые потребовались мне. Это не полный список того, что предлагает 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
│   └── my_x86_board
│       ├── bef_cr_fs_img.sh
│       ├── linux.config
│       ├── rootfs_overlay
│       └── users.txt
├── Config.in
├── configs
│   └── my_x86_board_defconfig
├── external.desc
├── external.mk
├── package
└── 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:

qcxb8hzlqdotxybnrnkon3rtmmm.png

В этом подменю будут содержаться наши пакеты из нашего 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) добавится.

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

e9lxn-mrffymfigyt2negm5yohc.png


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

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

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

y_91igfip21i_bmp3sbwjl9r8fm.png

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

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

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

v3f2sqkr0whuzumz5ydhcrxgbta.png

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

[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)

© Habrahabr.ru