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)

Вы можете помочь и перевести немного средств на развитие сайта

Теги:



Комментарии (20):

  1. DigitalSmile
    /#20079222

    Спасибо за серию статей!
    Еще бы кто-нибудь сделал серию по формированию файла Device Tree с глубоким погружением, цены бы такому человеку не было бы…

    • maquefel
      /#20079562

      А что конкретно в Device Tree вас интересует? Что именно непонятно?

      • DigitalSmile
        /#20080734

        Ну вот мы разрабатываем свою плату. Берем в правую руку даташит на процессор и периферию, в левую руку клавиатуру и файл с Device Tree. Что дальше? С чего начать описание? Как правильно мапить адреса, прерывания, регистры...? Если я чего-то не замапил — ядро этого не увидит? Или увидит но будет криво работать? В чем отличие Device Tree для ядра от Device Tree в моем флеше (почему-то по гайду от производителя их надо 2 — один для bootloader второй для ядра)?

        Короче говоря, хотелось бы ликбез какой-то с чего начинаем, какие параметры вписываем, как оно взаимодействует с ядром. Есть несколько источников в сети на elinux где кое-что описано, но общего понимания всего равно нет…

        Добавлю: сейчас наш процесс создания такого файла — это метод проб и ошибок, бессистемный.

        • maquefel
          /#20081084

          Я вас понял. Да такую статью я бы и сам почитал :-D.

          • DigitalSmile
            /#20081394

            Ну вот… Я уж губу раскатал думал нашел такого человека, который все расскажет :D

        • gosha-z
          /#20083640

          А это сильно зависит от процессора. Для начала можно поизучать уже имеющиеся. dtsi и. dts от других плат. И может понадобиться также и схема самой платы (например, для правильного описания gpio, pinctrl и led'ов)

          • DigitalSmile
            /#20088856

            Ну вот мы так и идем, даже демо плату купили… Только это как-то кустарно выглядит как способ разработки…

            • maquefel
              /#20088898

              Так большинство, по-моему, идет. На самом деле если глянуть, то все SoM, SoC в большинстве своем калька с Evaluation Board.
              Не так уж много делают новых плат — да и зачем.

              • DigitalSmile
                /#20088930

                Ответ на вопрос «зачем?» может занять много места :) Есть куча факторов, почему не стоит ИМХО делать кальку с Demo Board (начиная от выбора компонентов, заканчивая ошибками в разведении и недоступностью фич на камне). Поэтому для заказчика часто приходится делать что-то свое, иногда нестандартное.

                Взять к примеру HDMI — его щас лепят на все демо платы. Проблема с ним в том, что начиная с определенного времени надо заносить денюжку организации, которая владеет стандартом (неслабую надо отметить). Без лицензии тебе не продадут мост LVDS-HDMI. Есть запасы старых чипов, которые не требуют лицензии, но на серьезном серийном производстве полагаться на запасы нельзя (они имеют свойство заканчиваться). При этом на наш чип «православных» Display Port выходов никто не делал. Вот и приходится заниматься этой разработкой вслепую, методом проб и ошибок…

                • maquefel
                  /#20088958

                  Ну вот тогда вам и флаг в руки :-D со статьёй. В моей практике не так часто приходится, что-то принципиально новое разводить.

                  • DigitalSmile
                    /#20088964

                    Да, я вот и чувствую по формату беседы, что к этому и идет :D

                    • maquefel
                      /#20088990

                      Но вообще говоря сильно зависит от производителя камня. У texas отличные инструменты для pinmux, NXP тоже догоняет. А вот если плохо с документацией на камень, тогда все очень печально.

                      • DigitalSmile
                        /#20089016

                        Мы стараемся брать компоненты у проверенных компаний с хорошей документацией, только проблема возникает на стыке софта и харда. У нас отличные инженеры, которые все хорошо разведут и классные программисты, которые пишут хороший код. Только вот соединить их навыки из-за отсутствия теоретического материала и практического опыта сейчас крайне тяжело. Много времени уходит просто на анализ существующих драйверов, чтобы «сделать по аналогии» ну и тут же вносятся изменения в схему и консультации с инженерами. Иногда бывают тупики и приходится возвращаться назад.
                        В общем, жалко что никакого готового материала нет, надо и правда подумать о создании своего…

                • Boozlachu
                  /#20088976

                  maquefel подал не плохую мысль.
                  Действительно, если Вы начнёте писать статью по этой теме, то это даст хороший рост. Объяснить кому-то всегда сложнее, чем взять и сделать.
                  Я поэтому и начал писать про buildroot. Хорошая систематизация знаний и мозный стимул начать разбираться как следует

                  • maquefel
                    /#20088996

                    Ну вообще да. Просим статью.

            • gosha-z
              /#20089524

              Почему кустарно? Пользование текстовым редактором и чтение документации — это уже кустарщина?

              • DigitalSmile
                /#20089554

                Метод проб и ошибок, бессистемный анализ и глупое копирование без понимания сути — это кустарщина.

                • gosha-z
                  /#20089568

                  Почему бессистемный. Выкатывайте вашу плату, на вашей плате сделаем пример создания DT. Практика всегда лучше теории. Только давайте что-нибудь приличное и документированное, типа TI/NXP/Xilinx, от китайцев лучше держаться подальше, у них с документацией традиционно швах.

                  • DigitalSmile
                    /#20089672

                    Спасибо за предложение помощи! :)
                    Я думаю это уже не в рамках комментариев к хабру надо общаться. Чип у нас Atmel SAMA5D44 на первой итерации, после пробы пера хотим поменять на TI Cortex A-9 (пока еще не выбрали какой конкретно).