Разработка с помощью Yocto
IBM Senior DevOps Engineer & Integration Architect. Официальный DevOps ментор и коуч в IBM
Привет Хабр! Недавно принял участие в достаточно интересном воркшопе и хотел бы поделиться приобретенными навыками.
Микроконтроллерами я занимаюсь как хобби, так что основы и даже чуть больше понимаю, да я и сам своего рода Embedded Developer.
Немного предисловия
В мире встраиваемых систем существует множество инструментов для создания кастомных операционных систем. Однако Yocto выделяется особым способом: он предоставляет гибкую и мощную платформу для создания настраиваемых Linux-систем. В этой статье мы погрузимся в мир Yocto, изучив его принципы, особенности и возможности, чтобы разобраться, как этот инструмент может стать незаменимым ресурсом для разработчика в области встраиваемых систем.
Yocto Project — это набор инструментов, позволяющий создавать настраиваемые Linux-системы для встраиваемых устройств и систем. Он предоставляет набор средств, позволяющих разработчикам создавать специализированные Linux-дистрибутивы, оптимизированные под конкретные требования и характеристики встраиваемых устройств.
Основная идея Yocto заключается в предоставлении инструментов для построения собственных Linux-образов, начиная с исходного кода и заканчивая готовым для использования образом, полностью адаптированным под нужды конкретного проекта. Это позволяет создавать минимальные, оптимизированные и настраиваемые системы, необходимые для запуска на встраиваемых устройствах различных типов.
Основные компоненты Yocto включают в себя BitBake (система сборки пакетов), OpenEmbedded (набор рецептов для построения пакетов и файловой системы) и метаданные, определяющие параметры сборки, пакеты и конфигурации.
Yocto предоставляет гибкую настройку, позволяющую определить архитектуру, поддерживаемые пакеты, конфигурацию ядра Linux и множество других параметров. Это особенно ценно для разработчиков встраиваемых систем, поскольку позволяет создавать компактные, оптимизированные и полностью функциональные операционные системы, соответствующие требованиям и ограничениям встраиваемых устройств.
Yocto активно используется в индустрии встраиваемых систем, поскольку позволяет эффективно управлять процессом разработки и создавать специализированные Linux-системы для широкого спектра устройств: от мобильных устройств и роутеров до промышленного оборудования.
Что нам нужно из реквизита? Спасибо IBM, что заранее все предоставили.
Система-хост на базе Linux с минимум 60 ГБ доступного места на диске;
Релиз Yocto 3.1 (Dunfell) LTS;
Etcher для Linux;
Считыватель microSD-карт и сама карта;
Raspberry Pi 4;
Источник питания USB-C 5 В 3 А;
Ethernet-кабель и порт для сетевого подключения;
Wi-Fi маршрутизатор.
Начнем с BSP
Пакет поддержки платы (Board Support Package, BSP) представляет собой набор программного обеспечения, необходимого для поддержки определенного аппаратного оборудования в контексте разработки программного обеспечения. Этот пакет включает в себя драйверы устройств, загрузчики, файлы описания аппаратуры (device tree blobs), иногда дополнительное ПО для работы с железом и другие компоненты, обеспечивающие корректную работу операционной системы на конкретном оборудовании.
BSP обеспечивает связь между аппаратной платформой и операционной системой. Он включает конфигурации, необходимые для запуска операционной системы на конкретном устройстве, обеспечивая поддержку аппаратных компонентов, таких как процессоры, контроллеры устройств ввода/вывода (GPIO), интерфейсы коммуникации (например, Ethernet, USB), а также другие периферийные устройства.
В контексте проектов, использующих Yocto или OpenEmbedded, слои BSP добавляют поддержку конкретных устройств или семейств устройств в рамках сборки пользовательских Linux-образов. Они включают настройки сборки, необходимые для создания образов, оптимизированных под конкретные характеристики железа, что позволяет создавать настраиваемые операционные системы для различных встраиваемых устройств.
Использование BSP упрощает разработку, так как обеспечивает готовые инструменты и настройки, позволяющие быстро начать работу с определенной аппаратной платформой, избегая необходимости создания всего необходимого ПО и настроек с нуля.
Начнем с установки версии Yocto Dunfell в каталог с именем poky.
Клонирую репозиторий Yocto:
Открываю терминал и ввожу команду для клонирования репозитория Yocto версии Dunfell в новый каталог с именем poky:
git clone -b dunfell git://git.yoctoproject.org/poky.git poky
Перехожу в только что созданный каталог poky:
cd poky
Запускаю команду для инициализации окружения:
source oe-init-build-env
Это создаст новый каталог build
и настроит рабочее окружение для сборки проекта Yocto.
Редактирую файлы bblayers.conf
и local.conf
в каталоге build/conf
, чтобы настроить параметры проекта под мои требования.
bblayers.conf:
Если подробнее, то этот файл определяет, какие слои (layers) будут использоваться в вашем проекте Yocto. Слои содержат конфигурации и файлы для построения пакетов и образов. В bblayers.conf
мы добавляем пути к каталогам слоев, которые мы хотим включить в сборку. Это позволяет Yocto узнать, откуда брать компоненты для построения проекта.
local.conf:
Этот файл предоставляет широкий спектр настроек для нашего проекта. В нем мы можем указать целевые образы, параметры ядра Linux, опции файловой системы, переменные окружения, параметры компилятора, настройки сети и многое другое. Это место, где мы настраиваем конфигурацию сборки под наши конкретные потребности.
К примеру, в bblayers.conf
мы добавляем пути к слоям, чтобы Yocto знал, где искать рецепты пакетов, а в local.conf мы можем указать, какие образы создать, какие компоненты исключить из образа, настроить параметры ядра и т.д.
Например:
Выбор целевого образа:
IMAGE_FSTYPES = "ext4"
IMAGE_INSTALL_append = " package-name"
Настройка ядра Linux:
MACHINE_FEATURES_append = " bluetooth"
Настройка переменных среды:
export HTTP_PROXY = "http://proxy.example.com:8080"
Я же добавлю только одну конфигурацию в local.conf
MACHINE ?= "qemuarm"
Указываю тип образа, который хочу собрать, используя команду bitbake
bitbake core-image-minimal
Ожидаю завершения сборки:
Жду, пока сборка образа завершится. В результате образ будет доступен в директории tmp/deploy/images/raspberrypi4-64.
Сборка существующего BSP
Прежде чем продолжить, нам также нужно склонировать следующие зависимые слои на один уровень выше от этого каталога poky, чтобы каталоги слоя и poky находились рядом друг с другом:
$ git clone -b dunfell git://git.openembedded.org/meta-openembedded
$ git clone -b dunfell git://git.yoctoproject.org/meta-raspberrypi
Обратите внимание, что имя ветки зависимых слоев соответствует релизу Yocto для совместимости. Держите все три клонирования актуальными и синхронизированными с их удаленными версиями, используя периодические команды git pull. Слой meta-raspberrypi является BSP для всех Raspberry Pi. После того как эти зависимости на месте, можно собрать образ, настроенный для Raspberry Pi 4. Но прежде чем мы это сделаем, давайте изучим рецепты для общих образов Yocto:
Сначала перейдите в каталог, где вы склонировали Yocto:
$ cd poky
Затем перейдите в каталог, где находятся рецепты стандартных образов:
$ cd meta/recipes-core/images
Отобразите список рецептов для образов:
$ ls -1 core*
Показать рецепт для core-image-base
:
$ cat core-image-base.bb
Показать рецепт для core-image-minimal
:
$ cat core-image-minimal.bb
Показать рецепт для core-image-minimal-dev
:
$ cat core-image-minimal-dev.bb
Перейдите в каталог classes
внутри poky/meta
:
$ cd ../../classes
Наконец, отобразите файл класса core-image
:
$ cat core-image.bbclass
Важно отметить, что в этом классе доступен длинный список доступных IMAGE_FEATURES
, включая упомянутую функцию dev-pkgs
.
Стандартные образы, такие как core-image-minimal
и core-image-minimal-dev
, не зависят от конкретной машины. Мы создали core-image-minimal
как для эмулятора QEMU Arm, так и для платы BeagleBone Black. Мы могли бы сделать тоже самое для образа core-image-minimal
для Raspberry Pi 4. В отличие от этого, слой BSP включает рецепты образов, предназначенные для конкретной платы или серии плат.
Теперь давайте рассмотрим рецепт rpi-test-image
внутри слоя BSP meta-raspberrypi
, чтобы увидеть, как поддержка Wi-Fi и Bluetooth добавляется к core-image-base для Raspberry Pi 4:
Сначала перейдите на уровень выше от каталога, где вы клонировали Yocto:
$ cd ../../..
Затем перейдите в каталог внутри слоя BSP meta-raspberrypi
, где находятся рецепты образов для Raspberry Pi:
$ cd meta-raspberrypi/recipes-core/images
Отобразите список рецептов образов Raspberry Pi:
$ ls -1
Покажите рецепт rpi-test-image
:
$ cat rpi-test-image.bb
Обратите внимание, что переменная IMAGE_INSTALL
была переопределена для добавления packagegroup-rpi-test
и включения этих пакетов в образ.
Перейдите в соседний каталог packagegroups
внутри meta-raspberrypi/recipes-core
:
$ cd ../packagegroups
И, наконец, отобразите рецепт packagegroup-rpi-test
:
$ cat packagegroup-rpi-test.bb
Обратите внимание, что пакеты connman
, connman-client
и bluez5
включены в список зависимостей времени выполнения, чтобы полностью включить поддержку Wi-Fi и Bluetooth.
Наконец, давайте соберем образ rpi-test-image
для Raspberry Pi 4:
Сначала перейдите на уровень выше от каталога, где вы клонировали Yocto:
$ cd ../../..
Затем настройте ваше рабочее окружение BitBake:
$ source poky/oe-init-build-env build-rpi
Это настраивает множество переменных среды и помещает вас во вновь созданный каталог build-rpi
.
Затем добавьте следующие слои в ваш образ:
$ bitbake-layers add-layer ../meta-openembedded/meta-oe
$ bitbake-layers add-layer ../meta-openembedded/meta-python
$ bitbake-layers add-layer ../meta-openembedded/meta-networking
$ bitbake-layers add-layer ../meta-openembedded/meta-multimedia
$ bitbake-layers add-layer ../meta-raspberrypi
Порядок добавления этих слоев важен, поскольку слои meta-networking и meta-multimedia зависят от слоя meta-python. Если bitbake-layers add-layer или bitbake-layers show-layers начнут выдавать ошибки парсинга, удалите каталог build-rpi и перезапустите процесс сначала.
Убедитесь, что все необходимые слои были добавлены в образ:
$ bitbake-layers show-layers
В списке должно быть всего восемь слоев: meta
, meta-poky
, meta-yocto-bsp
, meta-oe
, meta-python
, meta-networking
, meta-multimedia
и meta-raspberrypi
.
Изучите изменения, внесенные предыдущими командами bitbake-layers add-laye
r в bblayers.conf
:
$ cat conf/bblayers.conf
В переменной BBLAYERS должны быть прописаны те же восемь слоев, что и на предыдущем шаге.
Перечислите машины, поддерживаемые слоем BSP meta-raspberrypi
:
$ ls ../meta-raspberrypi/conf/machine
Обратите внимание на наличие конфигураций машин raspberrypi4 и raspberrypi4–64.
Добавьте следующую строку в ваш файл conf/local.conf
:
MACHINE = "raspberrypi4-64"
Это переопределяет следующее значение по умолчанию в вашем файле conf/local.conf
:
MACHINE ??= "qemux86-64"
Установка переменной MACHINE на raspberrypi4–64 гарантирует, что создаваемый образ будет работать для Raspberry Pi 4.
Теперь добавьте ssh-server-openssh
к списку EXTRA_IMAGE_FEATURES
в вашем файле conf/local.conf
:
EXTRA_IMAGE_FEATURES ?= "debug-tweaks ssh-server-openssh"
Это добавляет SSH-сервер к образу для локального сетевого доступа.
И, наконец, соберите образ:
$ bitbake rpi-test-image
Сборка может занять от нескольких минут до нескольких часов при первом запуске, в зависимости от количества ядер CPU в вашем рабочем окружении. TARGET_SYS
должен быть aarch64-poky-linux
, а MACHINE
должен быть raspberrypi4-64
, так как этот образ предназначен для 64-битных ядер Arm Cortex-A72 в Pi 4.
После завершения сборки должен появиться файл с именем rpi-test-image-raspberrypi4-64.rootfs.wic.bz2
в каталоге tmp/deploy/images/raspberrypi4-64
:
$ ls -l tmp/deploy/images/raspberrypi4-64/rpi-test*wic.bz2
Обратите внимание, что rpi-test-image-raspberrypi4-64.rootfs.wic.bz2
является символической ссылкой, указывающей на фактический образ в том же каталоге. К имени образа добавляется целое число, обозначающее дату и время сборки, перед расширением wic.bz2
.
Теперь запишите этот образ на microSD-карту с помощью Etcher и загрузите его на ваш Raspberry Pi 4:
Вставьте microSD-карту в ваш компьютер.
Запустите Etcher.
Нажмите «Flash from file» в Etcher.
Найдите образ
wic.bz2
, который вы собрали для Raspberry Pi 4, и откройте его.Выберите microSD-карту, которую вы вставили на Шаге 1.
Нажмите «Flash from Etcher», чтобы записать образ.
Извлеките microSD-карту, когда процесс записи будет завершен.
Вставьте microSD-карту в Raspberry Pi 4.
Подайте питание на Raspberry Pi 4 через порт USB-C.
Убедитесь, что ваш Pi 4 успешно загрузился, подключив его к Ethernet и наблюдая, как индикаторы сетевой активности мигают.
В завершение хочу порекомендовать вам несколько бесплатных вебинаров про то кто такой Embedded developer, про электрические схемы, а также контроллеры и их программирование.