
Если вы занимаетесь созданием дистрибутивов Linux для встраиваемых систем, то, возможно, вас заинтересует проект Yocto. С его помощью можно создавать образы ОС в минимальных и оптимизированных конфигурациях для аппаратных платформ и приложений.
Особенно это полезно, если вам нужна ОС для встраиваемых систем с ограниченными ресурсами. Вы можете включить в состав создаваемого образа ОС только необходимые пакеты и программы, как готовые, так и разработанные специально для вашего устройства.
Компании, поставляющие устройства на базе микрокомпьютеров, могут комплектовать их ОС в необходимой конфигурации, а дистрибутив такой ОС они формируют с помощью Yocto.
В этой статье я расскажу о создании образов ОС с открытым кодом Napi Linux для модуля сбора данных от датчиков Front Control Compact, микрокомпьютеров roc-pc-rk3328 и rockpro64-rk3399, а также ОС для встраиваемых систем на базе Raspberry Pi.
Пока Napi Linux работает на ARM, но готовится сборка и для платформы x86.
Очень краткое введение в Yocto
В рамках проекта Yocto вы получите инструменты и компоненты, которые позволяют создавать образы для различных платформ:
Poky — референсная (принятая за образец) операционная система;
BitBake — система сборки;
OpenEmbedded — коллекция рецептов и метаданных для сборки различных пакетов программного обеспечения (ПО)
Poky содержит систему сборки OpenEmbedded, а также большой набор рецептов, организованных в виде иерархической системы слоёв, которые можно использовать в качестве полнофункционального шаблона для настраиваемой встроенной операционной системы.
Эти инструменты обеспечивают гибкость — можно настраивать конфигурацию ядра, добавлять или удалять компоненты, оптимизировать потребление ресурсов. Все это важно для встраиваемых систем, где ресурсы ограничены, и при этом важен размер образа, время загрузки, энергопотребление. С помощью Yocto можно создавать образы ОС (прошивки) для многих аппаратных платформ и архитектур.
В статье я расскажу о некоторых возможностях Yocto на конкретных примерах. Вам также доступна обширная документация Yocto (на английском языке) и различные ресурсы сообщества.
ОС с открытым кодом Napi Linux
В статье Собираем метрики с датчиков через Modbus и Telegraf я уже рассказывал о модуле сбора данных Front Control Compact отечественной сборки (рис. 1).

Рис. 1. Модуль Front Control Compact смонтирован на din-рейке
Этот модуль подходит для промышленного применения и автоматизации, например, умного дома. Он способен получать данные от сенсоров (датчиков) через Modbus RTU и Modbus TCP, а также может работать как прозрачный шлюз между Modbus RTU и Modbus TCP.
Важно, что для настройки и применения модуля не требуются навыки системного администрирования. Помимо ПО сбора данных Telegraf и InfluxDB2, доступен web-интерфейс NapiConfig, существенно упрощающей конфигурирование и обслуживание устройства.
В модуле Front Control Compact установлен 4-ядерный процессор RK3308 и ОЗУ объемом 512 Мбайт, память NAND, есть порт RS-485 с гальванической развязкой, порты Ethernet, USB и другое оборудование (рис. 2).

Рис. 2. Установка карты SD в модуле Front Control Compact
По умолчанию микрокомпьютер модуля загружает ОС NapiLinux из памяти NAND. Однако в модуле предусмотрена установка карты SD, на которую можно записать собственную прошивку.
ОС NapiLinux может работать на следующих платформах:
микрокомпьютер RockPro64 с процессором rk3399;
микрокомпьютер ROC-RK3288-CC с процессором rk3328;
микрокомпьютеры на базе NAPI (rk3308)
Структура разделов ОС NapiLinux
Операционная система NapiLinux специально оптимизирована для встраиваемых (Embedded) систем. Ее конфигурация выбрана для обеспечения длительной автономной работы модуля, возможности обновления системы и откатов обновлений.
Основное отличительное свойство NapiLinux от классических дистрибутивов (Debian, Ubuntu, DietPi) — дублирующие друг друга разделы с системой и отдельный раздел с пользовательскими данными. На рис. 3 показаны разделы для варианта 4 Гбайт NAND или eMMC. Если памяти больше, то система расширяет раздел до размеров памяти.

Рис. 3. Структура разделов ОС NapiLinux для варианта 4 Гбайт NAND или eMMC
На рис. 4 показано, что первый раздел mmcblk1p1 монтируется только для чтения, раздел mmcblk1p1 — для чтения и записи, а раздел mmcblk1p2 не монтируется.

Рис. 4. Размеры разделов и режимы монтирования
Система NapiLinux может загружаться как из раздела 1 (/dev/mmcblk1p1), так и из раздела 2 (/dev/mmcblk1p2).
При апдейте системы обновляется один из разделов (более "старый"). Если обновление прошло неудачно, система загрузится из другого раздела (рис. 5).

Рис. 5. Загрузка из другого раздела
Раздел 3 (/dev/mmcblk1p3) с пользовательскими данными содержит все конфиги, пользовательские файлы, базы данных и так далее. Чтобы выполнить резервное копирование, не нужно выгружать всю систему, достаточно сделать бэкап этого раздела.
Если нужно "обнулить" систему, достаточно стереть все данные раздела 3.
Web-интерфейс NapiConfig
В состав NapiLinux входит web-интерфейс NapiConfig, позволяющий управлять устройством сбора данных без использования командной строки Linux (рис. 6).

Рис. 6. Главное окно web-интерфейса настройки NapiConfig
Через web-интерфейс можно перезагрузить ОС сборщика данных или выключить его, контролировать работу различных сервисов и просматривать их журналы (рис. 7).

Рис. 7. Управление ОС устройства сборщика и сервисов NapiLinux
Не составит особого труда добавить в систему те или иные датчики, для которых есть или может быть создан шаблон конфигурации. Датчики можно активировать и отключать прямо через web-интерфейс (рис. 8).

Рис. 8. Управление датчиками через web-интерфейс
Кроме всего прочего, с помощью web-интерфейса NapiConfig можно просматривать графики изменения значений метрик датчиков (рис. 9).

Рис. 9. Графики изменения значений метрик датчиков
Сборка NapiLinux для Front Control Compact
ОС NapiLinux поставляется вместе с модулем Front Control Compact. Однако при необходимости вы можете самостоятельно собрать образ NapiLinux с помощью Yocto. Для NapiLinux доступны репозитории, значительно облегчающие этот процесс.
Подготовка VM для сборки образа
Система Yocto предназначена для кросс-разработки образа ОС. Это означает, что сборка образа ОС выполняется на каком-либо достаточно мощном сервере. После этого готовый образ переносится на микрокомпьютер тем или иным способом, например, через карту SD, и загружается уже на этом микрокомпьютере.
Системные требования для сервера сборки описаны в документации.
Я использовал Ubuntu Server 20.04.6 LTS, установленный на виртуальную машину WMware с объемом памяти 8 ГБайт, четырьмя ядрами процессора и диском 120 ГБайт. Заметим, что хотя количество ядер ускоряет процесс сборки, для исключения переполнения памяти рекомендуется использовать одно ядро на каждые 2 ГБайт оперативной памяти.
После установки Ubuntu выполните обновление, а затем добавьте в систему необходимые пакеты:
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install build-essential chrpath cpio debianutils diffstat file gawk gcc git iputils-ping libacl1 liblz4-tool locales python3 python3-git python3-jinja2 python3-pexpect python3-pip python3-subunit socat texinfo unzip wget xz-utils zstd
Дополнительно установите пакеты, облегчающие работу через консоль:
$ sudo apt install vim mc tree
Запуск сборки
На первом этапе создайте необходимые каталоги:
$ mkdir yocto
$ cd yocto
$ git clone --depth 1 git://git.yoctoproject.org/poky -b kirkstone
$ cd poky
Далее находясь в каталоге poky склонируйте репозитории:
$ git clone --depth 1 git://git.openembedded.org/meta-openembedded.git -b kirkstone
$ git clone --depth 1 git://git.yoctoproject.org/meta-arm.git -b kirkstone
$ git clone --depth 1 https://gitlab.nnz-ipc.net/pub/napilinux/meta-influx.git -b kirkstone
$ git clone --depth 1 https://gitlab.nnz-ipc.net/pub/napilinux/meta-nnz.git -b kirkstone
$ git clone --depth 1 https://github.com/sbabic/meta-swupdate -b kirkstone
Установите необходимое окружение:
$ source oe-init-build-env
Скопируйте файлы слоев и конфигурации:
$ cp ../meta-nnz/conf/bblayers.conf.sample.fc conf/bblayers.conf
$ cp ../meta-nnz/conf/local.conf.sample conf/local.conf
После этого запустите сборку проекта NapiLinux, содержащего кроме всего прочего Telegraf и InfluxDB2:
$ bitbake -k nnz-frontcontrol-image
Созданный образ запишите на карту SD, вставьте ее в модуль Front Control Compact и выполните загрузку.
Перенос образа NapiLinux на карту SD
Если вы работаете в ОС Microsoft Windows, то для переноса созданного образа ОС загрузите его из каталога артефактов ~/poky/build/tmp/deploy/images/napi-rk3308b-s на локальный диск, например, с помощью программы WinSCP.
Далее воспользуйтесь такими программами, как Rufus (рис. 10) или balenaEtcher, чтобы записать собранный образ ОС на карту SD.

Рис. 10. Запись образа ОС на карту SD с помощью Rufus
Сначала вам нужно скопировать файл с расширением имени *.wic из каталога артефактов на компьютер с Windows, а потом записать его на карту CD.
Если же вы работаете в ОС Linux, то сможете записать образ командой DD:
$ sudo dd if=nnz-frontcontrol-image-napi-rk3308b-s-20250121125034.rootfs.wic of=/dev/sdb bs=4M status=progress
Файл образа с расширением имени *.wic будет создан в каталоге ~/poky/build/tmp/deploy/images/napi-rk3308b-s. Вам нужно подставить в команду имя вашего файла. Также предполагается, что карте SD соответствует устройство /dev/sdb, у вас оно может быть другим.
Когда запись будет завершена, синхронизируйте буферы для безопасного извлечения карты SD:
$ sudo sync
Если вы собираете образ в виртуальной машине VMware, перед извлечением карты SD отсоедините соответствующее устройство USB от виртуальной машины, а также от хоста, на котором работает VMware.
Проверка собранного образа
Установите подготовленную карту SD с NapiLinux в устройство Front Control Compact, включите питание. Далее вам нужно найти адрес IP модуля, что можно сделать через web-интерфейс роутера — там нужно найти IP-адрес хоста с именем nap-rk3308b-s.
Также адрес устройства можно определить сканированием бесплатной программой Angry IP Scanner, которую можно скачать на сайте https://angryip.org/ для Windows, Mac OS и Linux. На обнаруженном устройстве должны быть открыты порты 22, 443 и 8082, а имя хоста должно определиться как napi-rk3308b-s.
В среде OS Linux для сканирования используйте утилиту nmap и запустите ее следующим образом:
sudo apt install nmap
sudo nmap -p 22,443,8082 192.168.0.0/24
Определив адрес IP модуля Front Control Compact тем или иным способом, откройте web-интерфейс по адресу вида http://xxx.xxx.xxx.xxx, где xxx.xxx.xxx.xxx — обнаруженный адрес IP. Вы также можете зайти на этот адрес IP через SSH, указав имя пользователя root и пароль napilinux.
При подключении к web-интерфейсу укажите логин admin и пароль admin. В процессе настройки вам нужно будет изменить этот пароль. На рис. 11 показано главное окно web-интерфейса NapiConfig.

Рис. 11. Главное окно web-интерфейса NapiConfig
Далее вы можете воспользоваться руководством NapiConfig: первый запуск для проверки работы собранного образа.
Через web-интерфейс NapiConfig вам будет доступна настройка параметров работы модуля Front Control Compact, подключение и конфигурирование датчиков, просмотр графиков изменения метрик и многое другое.
Сборка NapiLinux для roc-pc-rk3328 и rockpro64-rk3399
Операционную систему с открытым кодом NapiLinux можно установить не только на модуль Front Control Compact, но и на такие микрокомпьютеры, как roc-pc-rk3328 и rockpro64-rk3399. Большой объем оперативной памяти в этих микрокомпьютерах позволяет использовать не только Telegraf и InfluxDB2, но и Grafana (рис. 12).

Рис. 12. Панель с данными измерений от датчика ICPDAS DL-303
Сборку NapiLinux для rockpro64-rk3399 (рис. 13) и roc-pc-rk3328 (рис. 14) будем выполнять в ОС Debian 12.

Рис. 13. Микрокомпьютер rockpro64-rk3399

Рис. 14. Микрокомпьютер roc-pc-rk3328
Подготовка к сборке
Для сборки вам потребуется виртуальная машина с конфигурацией, аналогичной описанной выше. Например, в этой VM может быть 8 Гбайт оперативной памяти, 4 ядра и 100–120 Гбайт дисковой памяти. На каждое ядро требуется 2 Гбайт ОЗУ.
Установите на эту VM необходимые пакеты:
# apt install lz4 vim sudo gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python3 python3-pip python3-pyelftools python3-pexpect xz-utils debianutils iputils-ping libsdl1.2-dev xterm
Дополнительно настройте альтернативу /usr/bin/python3 для команды python:
# update-alternatives --install /usr/bin/python python /usr/bin/python3 1
Проверьте, установлена ли локаль (local — наборов языковых и региональных настроек) en_US.UTF-8. Для этого откройте на редактирование файл /etc/locale.gen, найдите там эту строку и убедитесь, что она не закрыта символом комментария.
Если закрыта, откройте ее и перечитайте настройки командой locale-gen:
# locale-gen
Создайте пользователя для сборки, например useryocto, и подключитесь этим пользователем к консоли SSH:
# useradd -m -s /bin/bash useryocto
# su – useryocto
Загрузите и распакуйте архив:
$ wget https://download.napilinux.ru/build/napi-kirkstone-build-env-0.1.20.3.tgz
$ tar -xvf napi-kirkstone-build-env-0.1.20.3.tgz
Удалите временный каталог сборки:
$ rm -rf ~/yocto/poky/build/tmp
Запуск сборки
Для запуска сборки перейдите в каталог yocto/poky:
$ cd yocto/poky
Установите переменные среды:
$ source oe-init-build-env
После этого отредактируйте файл local.conf:
$ vim conf/local.conf
Найдите в этом файле строку MACHINE и измените ее для той архитектуры, для которой нужно выполнить сборку:
MACHINE ?= "napi-rk3308b-s"
MACHINE ?= "napi-rk3308"
MACHINE ?= "roc-pc-rk3328"
MACHINE ?= "rockpro64-rk3399"
Если сборка выполняется для архитектуры rockpro64-rk3399, строка будет выглядеть следующим образом:
MACHINE ?= "rockpro64-rk3399"
Для микрокомпьютера roc-pc-rk3328 укажите MACHINE так:
MACHINE ?= "roc-pc-rk3328"
Если в виртуальной машине сборки мало памяти или слишком много ядер, добавьте в файл conf/local.conf дополнительные параметры:
BB_NUMBER_THREADS = "2"
PARALLEL_MAKE = "-j2"
Здесь указывается, что сборка будет выполняться в два потока.
Проверив и при необходимости отредактировав файл conf/local/conf, переходим к запуску сборки командой bitbake:
$ bitbake -k nnz-frontcontrol-image
Эта команда собирает образ с Web-интерфейсом NapiConfig.
Здесь вы можете указать такие варианты сборки:
nnz-frontcontrol-image
nnz-napi-image
nnz-napi-image-dev
nnz-napi-image-dev-noupdate
Наиболее полный вариант сборки получится, если задать параметр nnz-frontcontrol-image.
Сборка из репозитория NAPI
Выше мы рассказали о самом простом варианте сборки NapiLinux из заранее подготовленного архива. Другой вариант — использовать репозиторий https://gitlab.nnz-ipc.net/pub/napilinux/meta-nnz. В этом случае нужно придерживаться размещенной там инструкции.
Заметим, что при сборке из репозитория будет выполняться загрузка различных пакетов из разных мест, причем некоторые из них могут оказаться недоступными. В этом случае вы можете собрать образ и архива или загрузить недостающие компоненты самостоятельно из доступных репозиториев.
Перенос образа roc-pc-rk3328 и rockpro64-rk3399 для на карту SD
Когда сборка завершится, просмотрите файлы образов в следующем каталоге:
/home/useryocto/yocto/poky/build/tmp/deploy/images/
В подкаталоге roc-pc-rk3328 вы найдете файлы образов для roc-pc-rk3328, а если сборка выполнялась для rockpro64-rk3399, то ищите файлы образов в подкаталоге rockpro64-rk3399 этого каталога.
Скачайте файл с расширением имени *.wic, например, такой:
nnz-frontcontrol-image-roc-pc-rk3328-20250224140436.rootfs.wic
Далее этот файл можно записать на карту SD при помощи программ Rufus или BalenaEtcher в среде Microsoft Windows или с помощью команды DD в среде Linux, как было описано ранее в этой статье.
Для входа через SSH сразу после загрузки используйте логин root и пароль napilinux.
Сборка образа ОС для Raspberry Pi 3
Чтобы изучить принципы работы с Yocto, создадим образ минимальной конфигурации ОС для Raspberry Pi 3 (рис. 15).

Рис. 15. Собираем прошивку для этого микрокомпьютера
Подготовьте виртуальную машину с конфигурацией, описанной выше.
Создайте в своем рабочем каталоге подкаталог yocto и сделайте его текущим:
$ mkdir yocto
$ cd yocto
Далее выполните клонирование репозитория Poky, ветка kirkstone:
$ git clone git://git.yoctoproject.org/poky -b kirkstone
Если не указать конкретную ветку репозитория, то будет скопирована ветка master. В документации Yocto рекомендуют всегда указывать нужную вам ветку, чтобы все скопированное ПО было согласовано друг с другом.
После клонирования сделайте текущим каталог poky и проверьте статус:
$ cd poky
$ git status
On branch kirkstone
Your branch is up to date with 'origin/kirkstone'.
nothing to commit, working tree clean
Склонируйте слои openembedded и raspberrypi из ветки kirkstone:
$ git clone git://git.openembedded.org/meta-openembedded.git -b kirkstone
$ git clone git://git.yoctoproject.org/meta-raspberrypi -b kirkstone
Слой meta-openembedded включает рецепты для различных библиотек, утилит, графических интерфейсов, сетевых инструментов и других приложений для встраиваемых систем.
Слой meta-raspberrypi включает рецепты и конфигурации, специфичные для Raspberry Pi (драйверы, конфигурации ядра, и другие компоненты для этой платформы).
Прежде чем продолжить работу, убедитесь, что вы находитесь в каталоге poky.
Установите переменные среды:
$ source oe-init-build-env
Помимо установки переменных среды, будет создан каталог build, предназначенный для сборки. Вы можете посмотреть структуру каталогов внутри build, например, с помощью команды tree:
~/yocto/poky/build$ tree
.
└── conf
├── bblayers.conf
├── local.conf
└── templateconf.cfg
Если вы перезагрузили ОС или заново вошли в консоль пользователем, для продолжения работу нужно заново установить переменные среды.
Файл bblayers.conf
Для успешной сборки проекта очень важны файлы bblayers.conf и local.conf.
Файл bblayers.conf содержит определения слоев (layers) для вашего проекта Yocto. Слои содержат рецепты (recipes) и конфигурационные файлы для сборки компонентов системы.
На данном этапе подготовки проекта образа ОС для Raspberry Pi3 содержимое файла bblayers.conf выглядит так:
$ cat conf/bblayers.conf
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/home/frolov/yocto/poky/meta \
/home/frolov/yocto/poky/meta-poky \
/home/frolov/yocto/poky/meta-yocto-bsp \
"
Здесь и далее в статье вместо пользователя frolov укажите имя пользователя, который будет выполнять сборку.
Параметр POKY_BBLAYERS_CONF_VERSION указывает версию конфигурационного файла bblayers.conf. Номер версии увеличивается каждый раз, когда в файле происходят несовместимые изменения. Например, может измениться структура или формат файла, добавлены или удалены обязательные параметры, изменен порядок размещения слоев и так далее.
Параметр BBPATH указывает путь к корневому каталогу проекта Yocto. Переменная ${TOPDIR} содержит путь к каталогу проекта Yocto.
В параметре BBFILES задается список файлов рецептов (bitbake files) для сборки. Если он пуст, будут использоваться рецепты из слоев, указанных в параметре BBLAYERS:
/home/frolov/yocto/poky/meta: основной слой, содержащий базовые рецепты и конфигурации;
/home/frolov/yocto/poky/meta-poky: слой, содержащий рецепты и конфигурации, специфичные для Poky;
/home/frolov/yocto/poky/meta-yocto-bsp: слой, содержащий рецепты и конфигурации для поддержки различных платформ (Board Support Packages, BSP)
Находясь в каталоге сборки проекта /home/frolov/yocto/poky/build, добавьте ряд слоев, необходимых для сборки образа OS Raspberry Pi:
$ bitbake-layers add-layer ../meta-raspberrypi
$ bitbake-layers add-layer ../meta-openembedded/meta-oe
$ bitbake-layers add-layer ../meta-openembedded/meta-python
$ bitbake-layers add-layer ../meta-openembedded/meta-perl
$ bitbake-layers add-layer ../meta-openembedded/meta-multimedia
$ bitbake-layers add-layer ../meta-openembedded/meta-networking
$ bitbake-layers add-layer ../meta-openembedded/meta-gnome
$ bitbake-layers add-layer ../meta-openembedded/meta-xfce
Если вы собираете прошивку без оконного интерфейса, два последних слоя добавлять не нужно.
Теперь посмотрите содержимое файла bblayers.conf, чтобы увидеть добавленные слои:
$ cat conf/bblayers.conf
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/home/frolov/yocto/poky/meta \
/home/frolov/yocto/poky/meta-poky \
/home/frolov/yocto/poky/meta-yocto-bsp \
/home/frolov/yocto/poky/meta-raspberrypi \
/home/frolov/yocto/poky/meta-openembedded/meta-oe \
/home/frolov/yocto/poky/meta-openembedded/meta-python \
/home/frolov/yocto/poky/meta-openembedded/meta-perl \
/home/frolov/yocto/poky/meta-openembedded/meta-multimedia \
/home/frolov/yocto/poky/meta-openembedded/meta-networking \
/home/frolov/yocto/poky/meta-openembedded/meta-gnome \
/home/frolov/yocto/poky/meta-openembedded/meta-xfce \
"
Здесь были добавлены слои, расширяющие возможности дистрибутива, слои рецептов для Python, Perl, мультимедийных пакетов, сетевых пакетов и утилит, для рабочего стола Gnome и XFCE.
Файл local.conf
Теперь займемся файлом local.conf. Он нужен для настройки проекта Yocto. В нем задаются такие параметры, как целевая архитектура, настройки компилятора, включение или отключение определенных пакетов и многое другое.
Откройте файл для редактирования:
$ vim conf/local.conf
Прежде всего, найдите в нем строку «MACHINE ??= "qemux86-64"» и отредактируйте следующим образом:
MACHINE ??= "raspberrypi3-64"
Здесь мы указываем целевую платформу для сборки образа ОС — Raspberry Pi 3.
Чтобы контролировать ресурсы, выделенные для сборки ядра, добавьте в файл local.conf следующие строки:
BB_NUMBER_THREADS ?= "4"
PARALLEL_MAKE ?= "-j 4"
Здесь мы указали, что сборка будет проходить на 4 ядрах из 8. Если указать сразу все доступные ядра (количество ядер можно узнать командой lscpu), то работа с VM сборки для выполнения других задач может быть затруднена.
Если при сборке возникают ошибки, связанные с лицензированием драйверов или других компонентов Synaptics, добавьте в файл local.conf такую строку:
LICENSE_FLAGS_ACCEPTED += "synaptics-killswitch"
Запуск сборки базового образа в минимальной конфигурации
Подготовив файл local.conf, запустите сборку базового образа в минимальной конфигурации:
$ bitbake core-image-base
Этот процесс, запущенный в первый раз, может длиться очень долго, один или несколько часов в зависимости от производительности компьютера, где собирается образ (рис. 16).

Рис. 16. Первоначальная сборка выполняется очень долго
Повторные сборки при изменениях в проекте могут пойти быстрее за счет кеширования.
Если создание образа ОС прошло успешно, вы увидите на консоли такое сообщение:
NOTE: Tasks Summary: Attempted 4003 tasks of which 0 didn't need to be rerun and all succeeded.
После сборки различные артефакты образа core-image-base, созданные для платформы Raspberry Pi 3 64-bit, вы найдёте в каталоге:
/home/frolov/yocto/poky/build/tmp/deploy/images/raspberrypi3-64
Файлы с расширением имени *.ext3, tar.bz2, wic.bz2 представляют собой образы core-image-base для Raspberry Pi 3 64-bit. Вы можете записать их, например, на карту SD, вставить в Raspberry Pi 3 и загрузить собранную вами операционную систему.
В процессе сборки могут появляться различные сообщения об ошибках, например, о невозможности загрузки файлов:
ERROR: linux-raspberrypi-1_5.15.92+gitAUTOINC+509f4b9d68_14b35093ca-r0 do_fetch: Bitbake Fetcher Error: FetchError('Unable to fetch URL from any source.', 'git://github.com/raspberrypi/linux.git;name=machine;branch=rpi-5.15.y;protocol=https')
Если эти ошибки связаны с временной недоступностью соответствующего URL, можно попробовать запустить сборку повторно.
Перенос образа Raspberry Pi 3 на карту SD
В среде Microsoft Windows для переноса воспользуйтесь программой как Rufus или balenaEtcher.
В среде Linux используйте команду DD. Вначале скопируйте и распакуйте файл с расширением имени wic.bz2 (у вас имя файла будет другим):
$ cp core-image-base-raspberrypi3-64-20250112120805.rootfs.wic.bz2 core-image-base-raspberrypi3-64-20250112120805.rootfs.wic.bz2.copy
$ bunzip2 core-image-base-raspberrypi3-64-20250112104538.rootfs.wic.bz2
Далее скопируйте образ на карту SD (здесь предполагается, что карте SD соответствует устройство /dev/sdb, у вас оно может быть другим):
$ sudo dd if=core-image-base-raspberrypi3-64-20250112120805.rootfs.wic.bz2.copy.out of=/dev/sdb bs=4M status=progress
Когда запись будет завершена, синхронизируйте буферы для безопасного извлечения карты SD:
$ sudo sync
Добавляем сервисы и пакеты
Если вы уже собрали минимальный образ ОС для Raspberry Pi 3, то смогли убедиться, что к микрокомпьютеру нельзя подключиться по сети, так как в составе сборки нет сервиса openssh. Также нам пригодилась бы возможность управлять сервисами через systemd.
Добавьте в файл local.conf такие строки:
DISTRO_FEATURES:append = " systemd usrmerge"
VIRTUAL-RUNTIME_init_manager = "systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""
IMAGE_INSTALL:append = " openssh systemd systemd-machine-units"
Строка DISTRO_FEATURES:append = " systemd usrmerge" добавляет функции systemd и usrmerge к списку дистрибутива.
Функция systemd — система инициализации и управления системными службами. Что касается функции usrmerge, то она активирует использование объединенной файловой системы /usr, когда каталоги /bin, /sbin, и /lib являются символическими ссылками на соответствующие каталоги внутри /usr:
# ls -l /bin /sbin /lib
lrwxrwxrwx 1 root root 7 Mar 9 2018 /bin -> usr/bin
lrwxrwxrwx 1 root root 7 Mar 9 2018 /lib -> usr/lib
lrwxrwxrwx 1 root root 8 Mar 9 2018 /sbin -> usr/sbin
Строка VIRTUAL-RUNTIME_init_manager = "systemd" указывает, что systemd будет использована для запуска и остановки служб.
С помощью строки DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" включается возможность использования традиционной системы инициализации.
Строка VIRTUAL-RUNTIME_initscripts = "" очищает список скриптов инициализации — никакие дополнительные скрипты инициализации не будут включены в состав собираемого дистрибутива.
И, наконец, строка IMAGE_INSTALL:append = " openssh systemd systemd-machine-units" добавляет пакеты openssh, systemd и systemd-machine-units к списку пакетов, которые будут установлены в образ. Пакет systemd-machine-units содержит дополнительные юниты для systemd.
После редактирования файла local.conf снова запускаем сборку образа:
$ bitbake core-image-base
После сборки вы обнаружите, что в составе образа нет очень популярных редакторов nano и vim. Чтобы их добавить, отредактируйте строку IMAGE_INSTALL:append в файле local.conf:
IMAGE_INSTALL:append = " openssh systemd systemd-machine-units vim nano"
Здесь я просто дописал строку «vim nano» через пробел в конец строки IMAGE_INSTALL:append. Затем нужно заново запустить сборку образа.
После загрузки собранной ОС на Raspberry Pi 3 будут работать добавленные редакторы (рис. 17).

Рис. 17. Запущен добавленный в сборку редактор vim
На всякий случай завершить работу этого редактора можно, если нажать клавишу Esc, затем ввести двоеточие «:» и «q». Когда в файле были сделаны ненужные изменения, используйте «:q!».
Добавляем свой рецепт
Добавляя собственные рецепты, вы можете встраивать в сборку прошивки свои программы. Для создания рецептов в Yocto имеются специальные инструменты, однако для большего понимания этого процесса я сделал все вручную.
Сначала добавим простую программу на С из файла с именем example.c.
Дерево каталога для рецепта
В каталоге проекта нужно создать каталог для хранения собственного рецепта, а также сформировать структуру каталогов и файлов внутри него. В итоге у вас должна получиться такая структура:
~/yocto$ tree meta-mylayer
meta-mylayer
├── conf
│ └── layer.conf
├── COPYING.MIT
├── README
└── recipes-example
└── example
├── example_1.0.bb
└── files
├── example
│ └── example.c
└── MIT
5 directories, 6 files
Создайте в каталоге /home/frolov/yocto каталог meta-mylayer:
$ cd /home/frolov/yocto
$ mkdir -p meta-mylayer
Файл лицензии
Файл COPYING.MIT должен содержать текст лицензии MIT, если ваш рецепт и ПО публикуются под этой лицензией. Ниже представлен образец текста такой лицензии:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Создайте его при помощи, например, такой команды:
$ vim meta-mylayer/COPYING.MIT
Файл README
Что касается файла README, то в него вы можете записать информацию о зависимостях, патчах, о том, как устанавливать и как использовать ваш рецепт и ПО:
This README file contains information on the contents of the meta-mylayer layer.
Please see the corresponding sections below for details.
Dependencies
============
URI: <first dependency>
branch: <branch name>
URI: <second dependency>
branch: <branch name>
.
.
.
Patches
=======
Please submit any patches against the meta-mylayer layer to the xxxx mailing list (xxxx@zzzz.org)
and cc: the maintainer:
Maintainer: XXX YYYYYY <xxx.yyyyyy@zzzzz.com>
Table of Contents
=================
I. Adding the meta-mylayer layer to your build
II. Misc
I. Adding the meta-mylayer layer to your build
=================================================
Run 'bitbake-layers add-layer meta-mylayer'
II. Misc
========
--- replace with specific information about the meta-mylayer layer ---
Создать файл можно так:
$ vim meta-mylayer/README
Файл конфигурации рецепта layer.conf
Далее создайте в каталоге yocto/meta-mylayer каталог conf, а в нем — файл layer.conf, задающий конфигурацию слоя с вашим рецептом:
$ cd /home/frolov/yocto/meta-mylayer
$ mkdir conf
$ vim /home/frolov/yocto/meta-mylayer/conf/layer.conf
Содержимое файла layer.conf должно быть таким:
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"
# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "meta-mylayer"
BBFILE_PATTERN_meta-mylayer = "^${LAYERDIR}/"
BBFILE_PRIORITY_meta-mylayer = "6"
LAYERDEPENDS_meta-mylayer = "core"
LAYERSERIES_COMPAT_meta-mylayer = " kirkstone styhead walnascar"
Этот файл настраивает интеграцию пользовательского слоя с системой сборки Yocto, определяя пути, приоритеты, зависимости и совместимость.
Строка BBPATH позволяет найти конфигурации и классы в слое. Переменная ${LAYERDIR} определяется автоматически при сборке и указывает на корневой каталог текущего слоя.
Строка BBFILES указывает местоположение файлов рецептов (.bb) и дополнений к ним (.bbappend) внутри слоя.
Далее следует объявление коллекции рецептов слоя BBFILE_COLLECTIONS. При этом BBFILE_COLLECTIONS задает имя коллекции для данного слоя, BBFILE_PATTERN указывает путь, по которому будут искаться файлы этой коллекции, а BBFILE_PRIORITY задает приоритет слоя. Приоритет влияет на обработку файлов для устранения конфликтов.
Строка LAYERDEPENDS_meta-mylayer указывает, что данный слой зависит от базового слоя core.
И, наконец, строка LAYERSERIES_COMPAT_meta-mylayer перечисляет версии Yocto, с которыми совместим этот слой.
Каталог и файл рецепта
Далее нужно создать каталог recipes-example, а в нем — каталог example:
$ cd /home/frolov/yocto/meta-mylayer
$ mkdir recipes-example
$ cd recipes-example
$ mkdir example
$ cd example
В каталог yocto/meta-mylayer/recipes-example/example нужно записать файл рецепта example_1.0.bb:
$ vim /home/frolov/yocto/meta-mylayer/recipes-example/example/example_1.0.bb
Содержимое файла example_1.0.bb:
SUMMARY = "A simple example recipe"
DESCRIPTION = "This is an example recipe to demonstrate how to create a custom recipe in Yocto."
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://example/example.c"
# Указываем путь к исходному коду
S = "${WORKDIR}/example"
do_compile() {
${CC} ${CFLAGS} ${LDFLAGS} ${S}/example.c -o ${S}/example
}
do_install() {
install -d ${D}${bindir}
install -m 0755 ${S}/example ${D}${bindir}/example
}
Расскажем кратко о содержимом файла рецепта.
Строки SUMMARY, DESCRIPTION и LICENSE содержат краткое и подробное описание рецепта и тип лицензии, соответственно.
В строке LIC_FILES_CHKSUM нужно указать контрольную сумму файла лицензии, определенную следующим образом:
md5sum /home/frolov/yocto/meta-mylayer/COPYING.MIT
8cf727c7441179e7d76866522073754f /home/frolov/yocto/meta-mylayer/COPYING.MIT
Если контрольная сумма не указана, при сборке проекта можно получить предупреждение об ошибке.
Строка SRC_URI задает URI для исходного кода для сборки (в данном случае указан локальный файл).
В строке S задан путь к исходному коду в рабочем каталоге.
Функции do_compile и do_install выполняют компиляцию исходного кода и установку скомпилированного бинарного файла в целевую систему, соответственно.
Каталог файлов
Далее, создайте в каталоге yocto/meta-mylayer/recipes-example/example каталоги files и files/ example.
Что касается каталога files, то в него нужно положить файл с именем MIT и таким содержимым:
$ mkdir /home/frolov/yocto/meta-mylayer/recipes-example/example/file
$ vim /home/frolov/yocto/meta-mylayer/recipes-example/example/files/MIT
Содержимое файла:
MIT License
И, наконец, в каталог recipes-example/example/files/example нужно записать файл нашей программы example.c:
$ mkdir /home/frolov/yocto/meta-mylayer/recipes-example/example/files/example
$ vim /home/frolov/yocto/meta-mylayer/recipes-example/example/files/example/example.c
Содержимое файла:
#include <stdio.h>
int main() {
printf("Hello, Yocto!\n");
return 0;
}
После выполнения всех этих действий проверьте структуру каталога, например, командой tree:
$ cd /home/frolov/yocto
frolov@yocto-dev:~/yocto$ tree meta-mylayer
meta-mylayer
├── conf
│ └── layer.conf
├── COPYING.MIT
├── README
└── recipes-example
└── example
├── example_1.0.bb
└── files
├── example
│ └── example.c
└── MIT
Добавление слоя с рецептом
На следующем этапе нужно добавить строку слой я вашим рецептом в файл /home/frolov/yocto/poky/build/conf/bblayers.conf:
/home/frolov/yocto/meta-mylayer \
Должно получиться так:
$ cat /home/frolov/yocto/poky/build/conf/bblayers.conf
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/home/frolov/yocto/poky/meta \
/home/frolov/yocto/poky/meta-poky \
/home/frolov/yocto/poky/meta-yocto-bsp \
/home/frolov/yocto/meta-raspberrypi \
/home/frolov/yocto/meta-openembedded/meta-oe \
/home/frolov/yocto/meta-openembedded/meta-python \
/home/frolov/yocto/meta-openembedded/meta-perl \
/home/frolov/yocto/meta-openembedded/meta-multimedia \
/home/frolov/yocto/meta-openembedded/meta-networking \
/home/frolov/yocto/meta-openembedded/meta-gnome \
/home/frolov/yocto/meta-openembedded/meta-xfce \
/home/frolov/yocto/meta-mylayer \
"
Проверьте, что здесь была добавлена строка:
/home/frolov/yocto/meta-mylayer \
Добавление программы в сборку
Чтобы добавить программу example в сборку, отредактируйте файл /home/frolov/yocto/poky/build/conf/local.conf. Вам нужно добавить «example» в следующую строку:
IMAGE_INSTALL:append = " openssh systemd systemd-machine-units vim nano example"
Сборка рецепта и образа ОС
Теперь запустите сборку рецепта:
$ cd /home/frolov/yocto/poky/build
$ bitbake example
Когда рецепт соберется без ошибок, вы можете собрать образ ОС как обычно:
$ bitbake core-image-minimal
Запишите этот образ на SD карту и загрузите ее на Raspberry Pi 3. После этого подключитесь к микрокомпьютеру через SSH и запустите вашу программу:
root@raspberrypi3-64:~# /usr/bin/example
Hello, Yocto!
Как видите, нам удалось добавить собственную программу в сборку ОС, и ее можно запустить на Raspberry Pi (рис. 18).

Рис. 18. Запуск собственной программы example
Надеемся, вам понравилось работать с Yocto, и вы будете пользоваться этим инструментом для создания образов ОС встраиваемых систем, каких как ОС NapiLinux с открытым кодом и web-интерфейсом конфигурирования.